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)

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

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.


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...


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

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

4

Coba kueri sederhana ini. Ini bekerja dengan sempurna.

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

-3

Ini berhasil untuk saya di Oracle:

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

Pertanyaannya adalah tentang MySQL.
jelder

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.