sql >> Databáze >  >> RDS >> Sqlserver

SQL NOT IN nefunguje

SELECT foreignStockId
FROM   [Subset].[dbo].[Products]  

Pravděpodobně vrací NULL .

A NOT IN dotaz nevrátí žádné řádky, pokud je NULL s existuje v seznamu NOT IN hodnoty. Můžete je explicitně vyloučit pomocí IS NOT NULL jak je uvedeno níže.

SELECT stock.IdStock,
       stock.Descr
FROM   [Inventory].[dbo].[Stock] stock
WHERE  stock.IdStock NOT IN (SELECT foreignStockId
                             FROM   [Subset].[dbo].[Products]
                             WHERE  foreignStockId IS NOT NULL) 

Nebo přepište pomocí NOT EXISTS místo toho.

SELECT stock.idstock,
       stock.descr
FROM   [Inventory].[dbo].[Stock] stock
WHERE  NOT EXISTS (SELECT *
                   FROM   [Subset].[dbo].[Products] p
                   WHERE  p.foreignstockid = stock.idstock) 

Stejně jako mít sémantiku, kterou chcete, plán provádění pro NOT EXISTS je často jednodušší, jak je uvedeno zde.

Důvodem rozdílu v chování je logika se třemi hodnotami použitá v SQL. Predikáty mohou být vyhodnoceny jako True , False nebo Unknown .

A WHERE klauzule musí být vyhodnocena jako True aby byl řádek vrácen, ale to není možné s NOT IN když NULL je přítomen, jak je vysvětleno níže.

'A' NOT IN ('X','Y',NULL) je ekvivalentní 'A' <> 'X' AND 'A' <> 'Y' AND 'A' <> NULL)

  • 'A' <> 'X' =True
  • 'A' <> 'Y' =True
  • 'A' <> NULL =Unknown

True AND True AND Unknown vyhodnotí jako Unknown podle pravdivostních tabulek pro tři hodnotné logiky.

Následující odkazy obsahují další diskusi o výkonu různých možností.

  • Mám použít NOT IN , OUTER APPLY , LEFT OUTER JOIN , EXCEPT nebo NOT EXISTS ?
  • NOT IN vs. NOT EXISTS vs. LEFT JOIN / IS NULL :SQL Server
  • Left outer join vs NOT EXISTS
  • NOT EXISTS vs NOT IN


  1. Je možné definovat globální proměnné v postgresql

  2. Formát data SQL:Jak s ním zacházet chytře

  3. Podmíněný příkaz JOIN SQL Server

  4. Existuje SQL Server Profiler pro SQL Server Express?