SEÇ * NEREDE OLMADI


96

Sanırım bununla doğru yoldan gidiyorum ... Lütfen benim SQL'im en iyisi olmadığı için yanımda ol

Belirli hücrelerin diğerinde bulunmadığı bir tablodan her şeyi seçmek için bir veritabanını sorgulamaya çalışıyorum. Bu pek bir anlam ifade etmiyor ama umarım bu kod parçası

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

Yani temelde çalışanların listesi ve ayrıntılarını içeren bir masam var. Sonra, isimleri de dahil olmak üzere bazı diğer ayrıntıları içeren başka bir tablo. Eotm_dyn tablosunda ismin olmadığı yerde, yani onlar için giriş yok, tam olarak kim olduklarını veya başka bir deyişle tam olarak neyin eksik olduğunu görmek isterim.

Yukarıdaki sorgu hiçbir şey döndürmez, ancak 20 ismin eksik olduğunu biliyorum, bu yüzden açıkçası doğru anlamadım.

Biri yardım edebilir mi?

Yanıtlar:


163

Sorgunuzda tabloya katılmadınız.

Orijinal sorgunuz içinde hiç kayıt olmadıkça her zaman hiçbir şey döndürmez eotm_dyn; bu durumda her şeyi döndürür.

Bu tabloların birleştirilmesi gerektiğini varsayarak employeeID, aşağıdakileri kullanın:

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

Bu tabloları bir LEFT JOINanahtar kelimeyle birleştirebilir ve NULL'leri filtreleyebilirsiniz , ancak bu muhtemelen kullanmaktan daha az verimli olacaktır NOT EXISTS.


31
Yılda iki kez "NEREDE MEVCUT DEĞİL" e ihtiyacım var ve her zaman tam olarak nasıl kullanacağımı unutuyorum. Teşekkürler - bu örnek şimdi yer imlerine eklenecek.
Mateng

1
Birisi "LEFT JOIN + NULL filtresi MEVCUT DEĞİLDEN daha az verimli" için bir referans verebilir mi? Açık olabilir ama bunu belgelerde hiç görmedim. Teşekkürler.
toni07

2
@ toni07 Aslında bu bir efsane. LEFT JOIN kazanır. açıklamainextended.com/2009/ 09/18/… .. Quassnoi'nin blogu her zaman yardımcı bir kaynaktır.
Kaii

bunu HAVING yan tümcesinde nasıl kullanırım? akagroup by X having exist [row with employeeID = e.id]
phil294

@blauhirn: Aynen böyle
Quassnoi

84
SELECT * FROM employees WHERE name NOT IN (SELECT name FROM eotm_dyn)

VEYA

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

VEYA

SELECT * FROM employees LEFT OUTER JOIN eotm_dyn ON eotm_dyn.name = employees.name WHERE eotm_dyn IS NULL

1
NB! NOT INçalışmıyor gibi eğer beklenen namesahiptir nulldeğerleri. 36 dakika 20 saniyeden itibaren videoyu izleyin OTURUM: Her SQL Programcısının Bilmesi Gereken 10 Sorgu Ayarlama Tekniği (Kevin Kline, Aaron Bertrand) .
hlovdal

12

SOL BİRLEŞTİRME yapabilir ve birleştirilen sütunun BOŞ olduğunu iddia edebilirsiniz.

Misal:

SELECT * FROM employees a LEFT JOIN eotm_dyn b on (a.joinfield=b.joinfield) WHERE b.name IS NULL

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

eotm_dynBoş olmadığı sürece hiçbir kaydı döndürmez . Üzerinde kriterlerin çeşit gerekir SELECT name FROM eotm_dyngibi

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

iki tablonun bir yabancı anahtar ilişkisi ile bağlantılı olduğunu varsayarsak. Bu noktada, LEFT JOIN dahil olmak üzere çeşitli diğer seçenekleri kullanabilirsiniz. Bununla birlikte, optimizer genellikle bunları çoğu durumda aynı şekilde ele alır.


4

Bu ilgili soruya da bir göz atabilirsiniz . Bu kullanıcı, bir birleştirme kullanmanın bir alt sorgu kullanmaktan daha iyi performans sağladığını bildirdi.

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.