PILIH * DI MANA TIDAK ADA

95

Saya pikir saya akan mengambil jalan yang benar dengan yang satu ini ... Mohon bersabarlah karena SQL saya bukanlah yang terbaik

Saya mencoba membuat kueri database untuk memilih semuanya dari satu tabel di mana sel tertentu tidak ada di yang lain. Itu tidak terlalu masuk akal tapi saya berharap kode ini akan masuk akal

SELECT * from employees WHERE NOT EXISTS (SELECT name FROM eotm_dyn)

Jadi pada dasarnya saya memiliki satu tabel dengan daftar karyawan dan detailnya. Kemudian tabel lain dengan beberapa detail lainnya, termasuk namanya. Jika tidak ada nama di tabel eotm_dyn, artinya tidak ada entri untuk mereka, saya ingin melihat dengan tepat siapa mereka, atau dengan kata lain, melihat apa yang sebenarnya hilang.

Kueri di atas tidak mengembalikan apa-apa, tetapi saya tahu ada 20 nama yang hilang jadi saya jelas tidak melakukannya dengan benar.

Adakah yang bisa membantu?

Ciaran
sumber

Jawaban:

160

Anda tidak bergabung dengan tabel dalam kueri Anda.

Kueri asli Anda tidak akan selalu mengembalikan apa pun kecuali jika tidak ada catatan sama sekali eotm_dyn, dalam hal ini kueri akan mengembalikan semuanya.

Dengan asumsi tabel ini harus digabungkan employeeID, gunakan yang berikut ini:

SELECT  *
FROM    employees e
WHERE   NOT EXISTS
        (
        SELECT  null 
        FROM    eotm_dyn d
        WHERE   d.employeeID = e.id
        )

Anda dapat menggabungkan tabel-tabel ini dengan LEFT JOINkata kunci dan memfilternya NULL, tetapi ini kemungkinan akan kurang efisien daripada menggunakan NOT EXISTS.

Quassnoi
sumber
30
Saya membutuhkan "WHERE NOT EXISTS" dua kali setahun, dan saya selalu lupa bagaimana tepatnya menggunakannya. Terima kasih - contoh ini akan di-bookmark sekarang.
Mateng
1
Bisakah seseorang memberikan referensi untuk "LEFT JOIN + NULL filter is less efficiency than NOT EXISTS"? Itu bisa jelas, tapi saya tidak pernah melihatnya di dokumen. Terima kasih.
toni07
2
@ toni07 Sebenarnya, itu adalah legenda. LEFT JOIN menang. menjelaskanextended.com/2009/09/18/… .. Blog Quassnoi selalu merupakan sumber yang bermanfaat.
Kaii
bagaimana saya akan menggunakan ini dalam klausa HAVING? aliasgroup by X having exist [row with employeeID = e.id]
phil294
@blauhirn: begitu saja
Quassnoi
83
SELECT * FROM employees WHERE name NOT IN (SELECT name FROM eotm_dyn)

ATAU

SELECT * FROM employees WHERE NOT EXISTS (SELECT * FROM eotm_dyn WHERE eotm_dyn.name = employees.name)

ATAU

SELECT * FROM employees LEFT OUTER JOIN eotm_dyn ON eotm_dyn.name = employees.name WHERE eotm_dyn IS NULL
Robin Day
sumber
1
NB! NOT INtidak berfungsi seperti yang diharapkan jika namememiliki nullnilai. Tonton dari 36 menit 20 detik dalam video SESI: 10 Teknik Tuning Kueri Yang Harus Diketahui Setiap Pemrogram SQL (Kevin Kline, Aaron Bertrand) .
hlovdal
12

Anda dapat melakukan LEFT JOIN dan menegaskan kolom yang digabungkan adalah NULL.

Contoh:

SELECT * FROM employees a LEFT JOIN eotm_dyn b on (a.joinfield=b.joinfield) WHERE b.name IS NULL
Mike Tunnicliffe
sumber
8
SELECT * from employees
WHERE NOT EXISTS (SELECT name FROM eotm_dyn)

Tidak pernah mengembalikan catatan apa pun kecuali eotm_dynkosong. Anda perlu beberapa jenis kriteria tentang SELECT name FROM eotm_dynsuka

SELECT * from employees
WHERE NOT EXISTS (
    SELECT name FROM eotm_dyn WHERE eotm_dyn.employeeid = employees.employeeid
)

dengan asumsi bahwa dua tabel ditautkan oleh hubungan kunci asing. Pada titik ini Anda dapat menggunakan berbagai opsi lain termasuk LEFT JOIN. Namun, pengoptimal biasanya akan menanganinya dengan cara yang sama.

Cade Roux
sumber
4

Anda juga dapat melihat pertanyaan terkait ini . Pengguna tersebut melaporkan bahwa menggunakan gabungan memberikan kinerja yang lebih baik daripada menggunakan sub kueri.

Andre Miller
sumber