sql >> Database teknologi >  >> RDS >> Sqlserver

SQL select where not i underforespørgsel returnerer ingen resultater

Opdatering:

Disse artikler i min blog beskriver forskellene mellem metoderne mere detaljeret:

  • NOT IN vs. NOT EXISTS vs. LEFT JOIN / IS NULL :SQL Server
  • NOT IN vs. NOT EXISTS vs. LEFT JOIN / IS NULL :PostgreSQL
  • NOT IN vs. NOT EXISTS vs. LEFT JOIN / IS NULL :Oracle
  • NOT IN vs. NOT EXISTS vs. LEFT JOIN / IS NULL :MySQL

Der er tre måder at udføre sådan en forespørgsel på:

  • LEFT JOIN / IS NULL :

    SELECT  *
    FROM    common
    LEFT JOIN
            table1 t1
    ON      t1.common_id = common.common_id
    WHERE   t1.common_id IS NULL
    
  • NOT EXISTS :

    SELECT  *
    FROM    common
    WHERE   NOT EXISTS
            (
            SELECT  NULL
            FROM    table1 t1
            WHERE   t1.common_id = common.common_id
            )
    
  • NOT IN :

    SELECT  *
    FROM    common
    WHERE   common_id NOT IN
            (
            SELECT  common_id
            FROM    table1 t1
            )
    

Når table1.common_id er ikke nullbar, er alle disse forespørgsler semantisk ens.

Når den er nullbar, NOT IN er anderledes, da IN (og derfor NOT IN ) returner NULL når en værdi ikke matcher noget på en liste, der indeholder en NULL .

Dette kan være forvirrende, men kan blive mere indlysende, hvis vi husker den alternative syntaks for dette:

common_id = ANY
(
SELECT  common_id
FROM    table1 t1
)

Resultatet af denne tilstand er et boolsk produkt af alle sammenligninger på listen. Selvfølgelig en enkelt NULL værdien giver NULL resultat, som gengiver hele resultatet NULL også.

Vi kan aldrig sige bestemt, at common_id er ikke lig med noget fra denne liste, da mindst én af værdierne er NULL .

Antag, at vi har disse data:

common

--
1
3

table1

--
NULL
1
2

LEFT JOIN / IS NULL og NOT EXISTS returnerer 3 , NOT IN returnerer intet (da det altid vil evaluere til enten FALSE eller NULL ).

I MySQL , i tilfælde af ikke-nulbar kolonne, LEFT JOIN / IS NULL og NOT IN er en lille smule (adskillige procent) mere effektive end NOT EXISTS . Hvis kolonnen er nullbar, NOT EXISTS er den mest effektive (igen, ikke meget).

I Oracle , giver alle tre forespørgsler samme planer (en ANTI JOIN ).

I SQL Server , NOT IN / NOT EXISTS er mere effektive, da LEFT JOIN / IS NULL kan ikke optimeres til en ANTI JOIN af dens optimizer.

I PostgreSQL , LEFT JOIN / IS NULL og NOT EXISTS er mere effektive end NOT IN , sine er de optimeret til en Anti Join , mens NOT IN bruger hashed subplan (eller endda en almindelig subplan hvis underforespørgslen er for stor til at hash)



  1. Sådan grupperes efter måned i MySQL

  2. Hvad er det dobbelte bord i Oracle?

  3. Forskellige tidszone_typer på DateTime-objekt

  4. Hvordan MINUTE() virker i MariaDB