2012-03-13 16 views
7

Mam dwie tabele.mysql zapytanie dwie tabele, UNION i gdzie klauzula

kwerendy tak:

SELECT * FROM (
    Select requester_name,receiver_name from poem_authors_follow_requests as one 
UNION 
Select requester_name,receiver_name from poem_authors_friend_requests as two 
) as u 
where (LOWER(requester_name)=LOWER('user1') or LOWER(receiver_name)=LOWER('user1')) 

Używam UNION bo chcę uzyskać różne wartości dla każdego użytkownika, jeśli użytkownik istnieje w pierwszej tabeli i na sekundę.

Na przykład:

table1 

nameofuser 
peter 

table2 

nameofuser 
peter 

jeśli Peter jest na każdym stole powinna uzyskać nazwę jeden raz, ponieważ istnieje na obu tablicach.

Nadal otrzymuję jeden wiersz z pierwszego stołu i drugi z drugiego stołu. Co jest nie tak?

Każda pomoc doceniona.

+0

Czy kolumny w obu tabelach w tym samym czasie? Być może w jednej tabeli kolumna ma typ 'char', a w drugiej jest typu' varchar'there może ja niektóre przestrzenie .... –

+0

nop są obiema rodzajami pól – stefanosn

+0

W twoim miejscu, prawdopodobnie chcesz aby odwołać się do "u" przed każdym polem ... więc 'gdzie (LOWER (nazwa_requestera = = ...) jest to jednoznaczne z odpowiedzią, którą można zobaczyć w: http://stackoverflow.com/questions/5452233/ where-statement-after-a-union-in-sql –

Odpowiedz

11

Istnieją dwa problemy z SQL:

  1. (Jest nie pytanie, ale należy uważać) za pomocą WHERE ponad UNION zamiast tabel, tworzysz koszmar wydajności: MySQL utworzy tymczasową tabelę zawierającą UNION, a następnie przeszuka ją przez WHERE. Korzystanie z obliczeń na polu (LOWER(requester_name)) czyni to jeszcze gorszym.

  2. Powodem masz dwa rzędy to, że UNION DISTINCT będzie tłumić tylko prawdziwe duplikaty, tak krotka (someuser,peter) i krotka (someotheruser, peter) spowoduje powielania.

Edit

Aby (someuser, peter) duplikatem (peter, someuser) można użyć:

SELECT 
    IF(requester_name='peter', receiver_name, requester_name) AS otheruser 
FROM 
    ... 
UNION 
SELECT 
    IF(requester_name='peter', receiver_name, requester_name) AS otheruser 
FROM 
    ... 

więc wybrać tylko someuser które już znasz: peter

+0

Dzięki za powiedzenie mi, Eugen Rieck, masz rację, znajduje duplikaty powiedziałeś ... czy możesz mi powiedzieć, czy jest jakiś sposób na rozwiązanie tego problemu? (ktoś inny, peter) lub (peter, ktoś inny) powinien być duplikatem w moim przypadku – stefanosn

+0

Zmieniono moją odpowiedź! –

+0

Bardzo, bardzo podoba mi się podejście ! – stefanosn

-1

Powinieneś być w stanie użyć słowa kluczowego INTERSECT, zamiast wykonywać zapytanie zagnieżdżone na UNION.

SELECT member_id, name FROM a 
INTERSECT 
SELECT member_id, name FROM b 

można po prostu przepisany do

SELECT a.member_id, a.name 
FROM a INNER JOIN b 
USING (member_id, name) 

http://www.bitbybit.dk/carsten/blog/?p=71

+0

MySQL nie obsługuje słowa kluczowego "INTERSECT"! – onedaywhen

2

Trzeba klauzuli WHERE na obu wybiera:

select requester_name, receiver_name 
from poem_authors_follow_requests 
where LOWER(requester_name) = LOWER('user1') or LOWER(receiver_name) = LOWER('user1') 
union 
select requester_name, receiver_name 
from poem_authors_friend_requests 
where LOWER(requester_name) = LOWER('user1') or LOWER(receiver_name) = LOWER('user1') 

Dwa zapytania są niezależne od siebie , więc nie powinieneś próbować łączyć t rąbek inny niż przez union.

+0

Próbowałem, żeby nie działało jeszcze dwa razy !!! – stefanosn

0

Robisz związek, a następnie stosujesz klauzulę where. Otrzymasz unikalną kombinację "requester_name, receiver_name", a następnie klauzula where. Zastosowanie klauzuli WHERE w każdym wybierz ...

Select requester_name,receiver_name from poem_authors_follow_requests 
where (LOWER(requester_name)=LOWER('user1') 
     or LOWER(receiver_name)=LOWER('user1')) 
UNION 
Select requester_name,receiver_name from poem_authors_friend_requests 
where (LOWER(requester_name)=LOWER('user1') 
     or LOWER(receiver_name)=LOWER('user1')) 
1

Można użyć UNION, jeśli chcesz wybrać wiersze jeden po drugim f rom kilka tabel lub kilka zestawów wierszy z pojedynczej tabeli, wszystkie jako jeden zestaw wyników. UNION jest dostępny od wersji MySQL 4.0. Ta sekcja ilustruje, jak z niego korzystać. Załóżmy, że masz dwie tabele z listą potencjalnych i rzeczywistych klientów, trzecią z listą dostawców, od których kupujesz materiały eksploatacyjne, i chcesz utworzyć pojedynczą listę adresową, łącząc nazwy i adresy ze wszystkich trzech tabel. UNION zapewnia sposób na zrobienie tego. Zakładamy trzy tabele mają następującą zawartość:

http://w3webtutorial.blogspot.com/2013/11/union-in-mysql.html

0

w twojej Jeżeli oświadczenie, odniesienie alias „u” dla każdego pola porządkowy w WHERE.

Więc początku swojego gdzie stwierdzenie byłoby jak: where (LOWER(u.requester_name) = ...

To jest podobne do odpowiedzi można zobaczyć w: WHERE statement after a UNION in SQL?