Mysql: Başka bir tabloda olmayan bir tablodan satırları seçin


118

Bir tablodaki diğerinde görünmeyen tüm satırlar nasıl seçilir?

Tablo 1:

+-----------+----------+------------+
| FirstName | LastName | BirthDate  |
+-----------+----------+------------+
| Tia       | Carrera  | 1975-09-18 |
| Nikki     | Taylor   | 1972-03-04 |
| Yamila    | Diaz     | 1972-03-04 |
+-----------+----------+------------+

Tablo 2:

+-----------+----------+------------+
| FirstName | LastName | BirthDate  |
+-----------+----------+------------+
| Tia       | Carrera  | 1975-09-18 |
| Nikki     | Taylor   | 1972-03-04 |
+-----------+----------+------------+

Tablo1'deki Tablo2'de olmayan satırlar için örnek çıktı:

+-----------+----------+------------+
| FirstName | LastName | BirthDate  |
+-----------+----------+------------+
| Yamila    | Diaz     | 1972-03-04 |
+-----------+----------+------------+

Belki böyle bir şey çalışmalı:

SELECT * FROM Table1 WHERE * NOT IN (SELECT * FROM Table2)

Yanıtlar:


96

Başka bir yorumda belirttiğiniz gibi 300 sütununuz varsa ve tüm sütunlar üzerinde karşılaştırmak istiyorsanız (sütunların hepsinin aynı ad olduğunu varsayarak), NATURAL LEFT JOINiki tablo arasındaki eşleşen tüm sütun adlarını örtük olarak birleştirmek için a kullanabilirsiniz. tüm birleştirme koşullarını el ile sıkıcı bir şekilde yazmanız gerekmez:

SELECT            a.*
FROM              tbl_1 a
NATURAL LEFT JOIN tbl_2 b
WHERE             b.FirstName IS NULL

Bunun yalnızca sütunlardan hiçbiri NULL değerine sahip olmadığında beklendiği gibi çalıştığını unutmayın. MySQL'de NULL! = NULL, böylece ikinci tabloda yinelenen bir satır olsa bile NULL değeri olan her satır döndürülür.
Kyle Kochis

84
300 sütununuz varsa, veritabanınızı yeniden tasarlamalısınız.
Iharob Al Asimi 01

hey bu benim için de çalışıyor, teşekkürler! ancak yukarıda belirttiğiniz gibi satırlar 300'den fazla ise bu bir sorun olur mu?
thekucays

btw sorgusuyla ilgili hala kafam karıştı ... peki "b.İlkAdı null olduğu yerde" değiştirirsem, örneğin b.LastName boştur "olarak değiştirirsem? fark ne? Bunu sorduğum için üzgünüm,
sql'de

184

Alt seçimi bir sütun adına göre yapmanız gerekir, değil *.

Örneğin, idher iki tabloda da ortak olan bir alanınız varsa şunları yapabilirsiniz:

SELECT * FROM Table1 WHERE id NOT IN (SELECT id FROM Table2)

Daha fazla örnek için MySQL alt sorgu sözdizimine bakın .


1
açıklama için teşekkürler! ama gerçekten satır seçimini herhangi bir alana dayandırmam gerekmiyor, çünkü satırdaki herhangi bir alanın herhangi bir varyasyonuyla ilgileniyorum ...

Karşılaştırılacak yalnızca birkaç sütun varsa, @ Steve örneğine göre bir birleştirme yapabilirsiniz. Aslında birçok sütunlu iki tablodaki verilerin genel bir karşılaştırmasını istiyorsanız, muhtemelen bir MySQL fark aracı aramak istersiniz .
Stennie

2
Tablo2'de baktığınız sütun boş değerler içeriyorsa, bunun her zaman boş bir küme döndüreceğini unutmayın. Bunu birincil anahtara göre yapıyorsanız sorun değil, ancak bu sorguyu başka bağlamlarda kullanmaya çalışan kişilerle ilgili.
Mark Amery

4
Peki ya büyük veriden bahsediyorsak? Ve Tablo2 100 milyon satır içeriyor, örneğin?
16:31

Akıllı ve akıllıca cevap. Teşekkürler dostum
Anjana Silva

44
SELECT *
FROM Table1 AS a
WHERE NOT EXISTS (
  SELECT *
  FROM Table2 AS b 
  WHERE a.FirstName=b.FirstName AND a.LastName=b.Last_Name
)

EXISTS sana yardım edeceğim...


2
İyi yanıt, büyük veri kümeleri için ekonomik, teşekkürler.
ekerner

Kuvvetli. Büyük veri kümeleri için en iyi yanıt
Ian Chadwick

35

Standart bir LEFT JOIN sorunu çözebilir ve birleştirmedeki alanlar dizine alınmışsa,
daha hızlı olmalıdır.

SELECT *
FROM Table1 as t1 LEFT JOIN Table2 as t2 
ON t1.FirstName = t2.FirstName AND t1.LastName=t2.LastName
WHERE t2.BirthDate Is Null

peki, sanırım bu olmalı, btw neden WHERE t2.Birthdate Is Nullyerine AND t1.Birthdate = t2.Birthdate?

Çünkü bunu eklerseniz, her satır döndürülür, çıktıda yalnızca ikinci tabloda olmayan satırların görünmesi gerektiğini söylersiniz
Steve

1
Bu müthiş bir cevap, çünkü tüm satırlarını döndürmeyi gerektirmiyor Table2!
dotancohen

Katılıyorum, harika cevap. 4 masa arasında çok sayıda masam var, AND'yi iç birleşime koymak kesinlikle daha ekonomik olacak.
DR.

6

Deneyin:

SELECT * FROM table1
    LEFT OUTER JOIN table2
    ON table1.FirstName = table2.FirstName and table1.LastName=table2.LastName
    WHERE table2.BirthDate IS NULL

4

Bu basit sorguyu deneyin. Mükemmel çalışıyor.

select * from Table1 where (FirstName,LastName,BirthDate) not in (select * from Table2);

-3

Bu benim için Oracle'da çalıştı:

SELECT a.* 
    FROM tbl1 a 
MINUS 
SELECT b.* 
    FROM tbl2 b;

Soru MySQL hakkındaydı.
jelder

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.