Sqlserver
 sql >> база данни >  >> RDS >> Sqlserver

SQL изберете къде не в подзаявката не връща резултати

Актуализация:

Тези статии в моя блог описват разликите между методите по-подробно:

  • NOT IN срещу NOT EXISTS срещу LEFT JOIN / IS NULL :SQL Server
  • NOT IN срещу NOT EXISTS срещу LEFT JOIN / IS NULL :PostgreSQL
  • NOT IN срещу NOT EXISTS срещу LEFT JOIN / IS NULL :Oracle
  • NOT IN срещу NOT EXISTS срещу LEFT JOIN / IS NULL :MySQL

Има три начина да направите такава заявка:

  • 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
            )
    

Когато table1.common_id не е нула, всички тези заявки са семантично еднакви.

Когато е нула, NOT IN е различно, тъй като IN (и следователно NOT IN ) върне NULL когато стойност не съвпада с нищо в списък, съдържащ NULL .

Това може да е объркващо, но може да стане по-очевидно, ако си припомним алтернативния синтаксис за това:

common_id = ANY
(
SELECT  common_id
FROM    table1 t1
)

Резултатът от това условие е булев продукт на всички сравнения в списъка. Разбира се, един единствен NULL стойност дава NULL резултат, който изобразява целия резултат NULL също.

Никога не можем да кажем определено, че common_id не е равно на нищо от този списък, тъй като поне една от стойностите е NULL .

Да предположим, че имаме следните данни:

common

--
1
3

table1

--
NULL
1
2

LEFT JOIN / IS NULL и NOT EXISTS ще върне 3 , NOT IN няма да върне нищо (тъй като винаги ще се оценява на FALSE или NULL ).

В MySQL , в случай на колона без нула, LEFT JOIN / IS NULL и NOT IN са малко (няколко процента) по-ефективни от NOT EXISTS . Ако колоната е нула, NOT EXISTS е най-ефективният (отново не много).

В Oracle , и трите заявки дават едни и същи планове (ANTI JOIN ).

В SQL Server , NOT IN / NOT EXISTS са по-ефективни, тъй като LEFT JOIN / IS NULL не може да бъде оптимизиран за ANTI JOIN от неговия оптимизатор.

В PostgreSQL , LEFT JOIN / IS NULL и NOT EXISTS са по-ефективни от NOT IN , тъй като те са оптимизирани за Anti Join , докато NOT IN използва hashed subplan (или дори обикновен subplan ако подзаявката е твърде голяма за хеширане)



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Връщане на привилегии на таблица от свързан сървър в SQL Server (T-SQL примери)

  2. @@DATEFIRST – Вземете първия ден от седмицата в SQL Server

  3. Кой синтаксис на присъединяване е по-добър?

  4. Изберете изявление, за да намерите дубликати в определени полета

  5. Преобразувайте „datetimeoffset“ в „time“ в SQL Server (T-SQL примери)