Sqlserver
 sql >> Teknologi Basis Data >  >> RDS >> Sqlserver

SQL pilih di mana tidak dalam subquery tidak mengembalikan hasil

Pembaruan:

Artikel di blog saya ini menjelaskan perbedaan antara metode secara lebih rinci:

  • 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

Ada tiga cara untuk melakukan kueri seperti itu:

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

Ketika table1.common_id tidak dapat dibatalkan, semua kueri ini secara semantik sama.

Jika nullable, NOT IN berbeda, karena IN (dan, oleh karena itu, NOT IN ) kembalikan NULL ketika suatu nilai tidak cocok dengan apa pun dalam daftar yang berisi NULL .

Ini mungkin membingungkan tetapi mungkin menjadi lebih jelas jika kita mengingat sintaks alternatif untuk ini:

common_id = ANY
(
SELECT  common_id
FROM    table1 t1
)

Hasil dari kondisi ini adalah produk boolean dari semua perbandingan dalam daftar. Tentu saja, satu NULL nilai menghasilkan NULL hasil yang membuat seluruh hasil NULL juga.

Kami tidak pernah bisa mengatakan dengan pasti bahwa common_id tidak sama dengan apa pun dari daftar ini, karena setidaknya salah satu nilainya adalah NULL .

Misalkan kita memiliki data ini:

common

--
1
3

table1

--
NULL
1
2

LEFT JOIN / IS NULL dan NOT EXISTS akan mengembalikan 3 , NOT IN akan mengembalikan tidak ada (karena akan selalu dievaluasi menjadi FALSE atau NULL ).

Di MySQL , jika pada kolom yang tidak dapat dibatalkan, LEFT JOIN / IS NULL dan NOT IN sedikit (beberapa persen) lebih efisien daripada NOT EXISTS . Jika kolom nullable, NOT EXISTS adalah yang paling efisien (sekali lagi, tidak banyak).

Di Oracle , ketiga kueri menghasilkan paket yang sama (sebuah ANTI JOIN ).

Di SQL Server , NOT IN / NOT EXISTS lebih efisien, karena LEFT JOIN / IS NULL tidak dapat dioptimalkan ke ANTI JOIN oleh pengoptimalnya.

Di PostgreSQL , LEFT JOIN / IS NULL dan NOT EXISTS lebih efisien daripada NOT IN , karena dioptimalkan ke Anti Join , sedangkan NOT IN menggunakan hashed subplan (atau bahkan subplan biasa jika subquery terlalu besar untuk di-hash)



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Cara Mengubah Nilai untuk Edit X Teratas dan Memilih Baris X Teratas di SQL Server Management Studio (SSMS) - Tutorial SQL Server / TSQL Bagian 20

  2. Apakah mungkin untuk menentukan kondisi di Count()?

  3. Cara menonaktifkan semua Batasan Kunci Asing di Database SQL Server - Tutorial SQL Server / TSQL Bagian 77

  4. Hapus SCHEMABINDING dari Fungsi Buatan Pengguna di SQL Server

  5. Fungsi Skalar ODBC untuk Tanggal dan Waktu di SQL Server (Contoh T-SQL)