Mysql: Pilih baris dari tabel yang tidak ada di tabel lain

118

Bagaimana cara memilih semua baris dalam satu tabel yang tidak muncul di tabel lain?

Tabel 1:

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

Meja 2:

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

Contoh keluaran untuk baris di Tabel1 yang tidak ada di Tabel2:

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

Mungkin sesuatu seperti ini seharusnya berhasil:

SELECT * FROM Table1 WHERE * NOT IN (SELECT * FROM Table2)
Christopher Rapcewicz
sumber

Jawaban:

96

Jika Anda memiliki 300 kolom seperti yang Anda sebutkan di komentar lain, dan Anda ingin membandingkan di semua kolom (dengan asumsi semua kolom adalah nama yang sama), Anda bisa menggunakan NATURAL LEFT JOINuntuk secara implisit menggabungkan semua nama kolom yang cocok di antara dua tabel sehingga Anda tidak perlu mengetik semua kondisi penggabungan secara manual:

SELECT            a.*
FROM              tbl_1 a
NATURAL LEFT JOIN tbl_2 b
WHERE             b.FirstName IS NULL
Zane Bien
sumber
Perhatikan bahwa ini hanya berfungsi seperti yang diharapkan jika tidak ada kolom yang memiliki nilai NULL. Di MySQL NULL! = NULL sehingga setiap baris yang memiliki nilai NULL akan dikembalikan meskipun ada baris duplikat di tabel kedua.
Kyle Kochis
84
Jika Anda memiliki 300 kolom, Anda harus mendesain ulang database Anda.
Iharob Al Asimi
hai ini bekerja untuk saya juga, terima kasih! tetapi apakah itu menjadi masalah jika barisnya> 300 seperti yang Anda sebutkan di atas?
thekucays
saya masih bingung tentang query btw..bagaimana jika saya mengubah "di mana b.FirstName adalah null" menjadi "di mana b.LastName adalah null" misalnya? apa bedanya? saya minta maaf untuk menanyakan ini, saya masih baru di sql: D
thekucays
184

Anda perlu melakukan subpilih berdasarkan nama kolom, bukan *.

Misalnya, jika Anda memiliki idbidang yang sama untuk kedua tabel, Anda dapat melakukan:

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

Lihat sintaks subkueri MySQL untuk contoh lainnya.

Stennie
sumber
1
terimakasih atas klarifikasinya! tetapi saya benar-benar tidak perlu mendasarkan pemilihan baris pada bidang apa pun, karena saya tertarik pada variasi apa pun dari bidang apa pun di baris ...
Jika hanya ada beberapa kolom untuk dibandingkan, Anda dapat melakukan penggabungan sesuai contoh @ Steve. Jika Anda sebenarnya meminta perbandingan umum data dalam dua tabel dengan banyak kolom, Anda mungkin ingin mencari alat bantu MySQL .
Stennie
2
Perhatikan bahwa ini akan selalu mengembalikan satu set kosong jika kolom yang Anda lihat di Tabel2 berisi nulls. Bukan masalah jika Anda melakukannya berdasarkan kunci utama, tetapi relevan untuk orang-orang yang mencoba menggunakan kueri ini dalam konteks lain.
Mark Amery
4
Tetapi bagaimana jika kita berbicara tentang data besar? Dan Table2 berisi 100 juta baris, misalnya?
frops
Jawaban cerdas dan cerdas. Terima kasih kawan
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 akan membantumu...

Ruzbeh Irani
sumber
2
Jawaban bagus, ekonomis untuk kumpulan data besar, terima kasih.
ekerner
Kuat. Jawaban terbaik untuk kumpulan data besar
Ian Chadwick
35

Standar LEFT JOIN dapat menyelesaikan masalah dan, jika field pada join diindeks,
juga harus lebih cepat

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
Steve
sumber
baiklah, saya rasa itu pasti itu, btw kenapa WHERE t2.Birthdate Is Nullmalah AND t1.Birthdate = t2.Birthdate?
Karena jika Anda menambahkan itu, maka setiap baris akan dikembalikan, Anda mengatakan bahwa dalam output seharusnya hanya muncul baris tidak ada di tabel kedua
Steve
1
Ini adalah jawaban yang bagus, karena tidak perlu mengembalikan semua baris Table2!
dotancohen
Saya setuju, jawaban yang bagus. Saya memiliki tabel banyak orang di antara 4 tabel, menempatkan DAN di gabungan dalam pasti akan lebih ekonomis.
DR.
6

Mencoba:

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

Coba kueri sederhana ini. Ini bekerja dengan sempurna.

select * from Table1 where (FirstName,LastName,BirthDate) not in (select * from Table2);
Vijesh
sumber
-3

Ini berhasil untuk saya di Oracle:

SELECT a.* 
    FROM tbl1 a 
MINUS 
SELECT b.* 
    FROM tbl2 b;
Gennady Sorochan
sumber
Pertanyaannya adalah tentang MySQL.
jelder
-6
SELECT a.* FROM 
FROM tbl_1 a
MINUS
SELECT b.* FROM 
FROM tbl_2 b
Ingrid R. Forsale
sumber