2013-04-08 14 views
5

próbuję komponować SELECT dla MySQL, który wybrać z stole, co nie istnieje w tabeli B. Na przykład:Wybierz z tabeli A, które nie istnieje w tabeli B

Tabela A:

+------+ 
| BAND | 
+------+ 
| 1 | 
| 2 | 
| 3 | 
| 4 | 
| 5 | 
+------+ 

Tabela B:

+------+ 
| HATE | 
+------+ 
| 1 | 
| 5 | 
+------+ 

Więc jeśli tabela a wszystkie zespoły, a tabela B to zespoły, których nienawidzę, to chcę tylko zespoły nie nienawidzę. Tak więc wynik wyboru powinien być:

+------+ 
| BAND | 
+------+ 
| 2 | 
| 3 | 
| 4 | 
+------+ 

Jak napisać do tego celu pojedyncze wybory? Oto moja ostatnia próba:

SELECT * FROM A LEFT JOIN B ON A.BAND = B.HATE WHERE B.HATE IS NULL; 

EDYCJA: Powyższa linia została naprawiona! Zobacz komentarze poniżej ... "= NULL" versus "IS NULL".

+1

@Michelle zapytanie wydaje się być w porządku. dlaczego mówisz, że to nie działa? – Barranka

+0

Zobacz mój komentarz poniżej. Dla każdego, kto ma taki sam problem, "IS NULL" nie jest tym samym, co "= NULL" w MySQL. Próbowałem w jedną stronę, a zapytanie działa, w przeciwnym razie zwraca pusty zestaw. Dziwne!!! – TSG

+0

Nie tylko w MySQL, ale w dowolnym dialekcie SQL. Wartość 'NULL' w SQL ma właściwość bycia różną od jakiejkolwiek innej wartości, włączając w to inny' NULL'. Z tego powodu nie możesz oczekiwać, że '= NULL' będzie działał na zapytaniu SQL ... musisz użyć' IS NULL'. – Barranka

Odpowiedz

16

użyłbym sprzężenia

select A.* 
from A left join B on A.BAND = B.HATE 
where B.HATE IS NULL; 

Pamiętaj: Tworzenie odpowiednich indeksów na stole

+0

To prawie identyczne z tym, co próbowałem (zobacz odpowiedź powyżej). Pytasz tylko o A. * w zamian za polecenie select ... może to jest problem. – TSG

+0

i powinno dać ci właściwą odpowiedź! (przy okazji, napisałem to przed twoją edycją). To powinno zwrócić to, czego potrzebujesz. Lub dlaczego mówisz, że nie zwraca tego, czego potrzebujesz? – Barranka

+0

OK - Znalazłem problem! Testowałem pod kątem "B.HATE = NULL", a nie "B.HATE IS NULL". Mój tekst powyżej był tym, co użyłem do stworzenia mojego polecenia SQL, ale kiedy faktycznie wpisałem kod (w ciąg PHP), zmieniłem go na = NULL. Dziwne, że są różne !? – TSG

5

Można użyć IN, ale jest to bardzo nieefektywne:

SELECT * FROM tableA WHERE id NOT IN (SELECT id FROM tableB) 
+2

Dlaczego jest to lepsze niż użycie sprzężenia? –

+2

Myślę, że jest to powolne, jeśli tabele A lub B są duże (dla małych tabel różnica w wydajności jest praktycznie zerowa) – Barranka

+1

Nigdy nie powiedziałem, że było lepiej, faktycznie mówię coś przeciwnego. 'IN' jest do bani, ponieważ uruchamia wewnętrzne zapytanie dla każdego zaznaczonego wiersza (czyli dla każdego wiersza w' tableA'). –

0
SELECT * FROM tableA WHERE id NOT EXISTS (SELECT DISTINCT id FROM tableB) 

lub

SELECT * FROM tableA WHERE id NOT EXISTS (SELECT id FROM tableB GROUP BY id) 
-2
SELECT BAND FROM A WHERE BAND NOT EXISTS(SELECT DISTINCT HATE FROM B) 

LUB

SELECT BAND FROM A WHERE NOT EXISTS (SELECT HATE FROM B WHERE A.BAND = B.HATE); 
Powiązane problemy