Oracle
 sql >> Teknologi Basis Data >  >> RDS >> Oracle

NOT IN seleksi dengan nilai NULL

Pertama sedikit teori:Null (SQL)

Bagian terpenting bagi kami dari tautan di atas:

Perbandingan dengan NULL dan logika tiga nilai (3VL)

Karena Null bukan anggota dari domain data apa pun, itu tidak dianggap sebagai "nilai", melainkan penanda (atau pengganti) yang menunjukkan tidak adanya nilai. Karena itu, perbandingan dengan Null tidak akan pernah menghasilkan Benar atau Salah, tetapi selalu dalam hasil logis ketiga,Tidak Diketahui.[8] Hasil logis dari ekspresi di bawah ini, yang membandingkan nilai 10 dengan Null, adalah Tidak Diketahui:

SELECT 10 = NULL       -- Results in Unknown

sehingga perbandingan keduanya:x = NULL dan x <> NULL mengevaluasi ke NULL(tidak diketahui).

SQL mengimplementasikan tiga hasil logis, jadi implementasi SQL harus menyediakan logika tiga nilai khusus (3VL). Aturan yang mengatur logika tiga nilai SQL ditunjukkan pada tabel di bawah ini (p andq mewakili status logika)"[9] Tabel kebenaran yang digunakan SQL untuk AND, OR, dan NOT sesuai dengan fragmen umum dari logika tiga nilai Kleene dan ukasiewicz ( yang berbeda dalam definisi implikasinya, namun SQL tidak mendefinisikan operasi seperti itu).

+---------+-------------+-------------+-------------+-----------+--------+
|    p    |        q    |     p OR q  |     p AND q |    p = q  |p != q  |
+---------+-------------+-------------+-------------+-----------+--------+
| True    |     True    |     True    |     True    |   True    | False  |
| True    |     False   |     True    |     False   |   False   | True   |
| True    |     Unknown |     True    |     Unknown |   Unknown | Unknown|
| False   |     True    |     True    |     False   |   False   | True   |
| False   |     False   |     False   |     False   |   True    | False  |
| False   |     Unknown |     Unknown |     False   |   Unknown | Unknown|
| Unknown |     True    |     True    |     Unknown |   Unknown | Unknown|
| Unknown |     False   |     Unknown |     False   |   Unknown | Unknown|
| Unknown |     Unknown |     Unknown |     Unknown |   Unknown | Unknown|
+---------+-------------+-------------+-------------+-----------+--------+

Pengaruh Tidak Diketahui dalam klausa WHERE

Logika tiga nilai SQL ditemukan dalam Bahasa Manipulasi Data (DML) dalam perbandingan predikat pernyataan dan kueri DML. Klausa WHERE menyebabkan pernyataan DML bertindak hanya pada baris yang predikatnya bernilai True.

Jadi singkatnya:klausa WHERE memperlakukan NULL sebagai FALSE

Sekarang pertimbangkan kasus yang lebih sederhana:

SELECT * FROM T1;

|      X |
|--------|
|      1 |
| (null) |

dan kueri:

SELECT * FROM t1 WHERE x IN (1, NULL);

Kueri di atas adalah singkatan dari yang ini:

SELECT * FROM t1 
WHERE x = 1
  OR  x = NULL

Untuk baris kedua dari tabel t ( x =NULL) kondisi ini terlihat seperti:

WHERE NULL = 1
   OR NULL = NULL

jadi kondisi ini untuk baris x=NULL mengevaluasi ke NULL karena NULL=1 adalah NULL, NULL=NULL adalah NULL, dan NULL OR NULL juga NULL (silakan lihat tabel 3VL di atas).

Sekarang pertimbangkan kasus yang lebih aneh:

SELECT * FROM t1 WHERE x NOT IN (1, NULL);

Klausa ini x NOT IN (1, NULL) setara dengan NOT ( x IN (1, NULL) )
jadi sama dengan:

NOT (
  x = 1
  OR
  x = NULL
)

dan menurut hukum De Morgan setara dengan:

NOT ( x = 1 ) AND NOT ( x = NULL )

dan (jika kita mengganti NOT x = y dengan x <> y ) itu juga setara dengan:

 x <> 1 AND x <> NULL

Harap perhatikan baik-baik kondisi terakhir:

WHERE 
x <> 1 AND x <> NULL

Kita tahu dari x <> NULL selalu mengevaluasi ke NULL. Kita juga mengetahui dari tabel 3VL di atas, bahwa keduanya true AND NULL adalah NULL dan false AND NULL mengevaluasi ke FALSE, sehingga seluruh kondisi selalu mengevaluasi ke FALSE atau NULL, tetapi tidak pernah mengevaluasi ke TRUE.

Oleh karena itu kueri dengan kondisi ini:

SELECT .....
WHERE x NOT IN ( NULL, whatever)

selalu mengembalikan hasil yang kosong

Dan sekarang pertanyaan Anda, yang juga membuat penasaran:

SELECT * FROM t1
WHERE (id, val) NOT IN (select id, val from data2);

yang dapat ditulis ulang (menggunakan nilai konstan) menjadi:

SELECT * FROM t1
WHERE (id, val) NOT IN (
       (1, null),
       (2, 2 )
)

Kueri ini menggunakan apa yang disebut ekspresi nilai baris

Pada dasarnya suatu kondisi menggunakan ekspresi nilai baris seperti ini

(a, b) = (x, y)

setara dengan yang ini:

a = x AND b = y

jadi kueri di atas dapat ditulis ulang menjadi yang ini:

SELECT * FROM t1
WHERE NOT (
   id = 1 AND val = NULL
   OR
   id = 2 AND val = 2
)

Menurut hukum De Morgan ini identik dengan:

SELECT * FROM t1
WHERE 
   NOT ( id = 1 AND val = NULL )
   AND
   NOT ( id = 2 AND val = 2 )

dan selanjutnya ke:

SELECT * FROM t1
WHERE 
   ( id <> 1 OR val <> NULL )
   AND
   ( id <> 2 OR val <> 2 )

Sejak bagian pertama ( id <> 1 OR val <> NULL ) dari kondisi bernilai benar hanya dalam kasus di mana id <> 1 (silakan lihat tabel 3VL di atas), kondisi ini dapat disederhanakan menjadi:

SELECT * FROM t1
WHERE 
   ( id <> 1 )
   AND
   ( id <> 2 OR val <> 2 )

dan selanjutnya (menurut hukum De Morgan) menjadi:

SELECT * FROM t1
WHERE 
   id <> 1 AND id <> 2
   OR
   id <> 1 AND  val <> 2

jadi bukan (1,1) atau (2,2) dari sumber data1 mematuhi syarat-syarat tersebut.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Instal klien Oracle Instan ke dalam wadah Docker untuk Python cx_Oracle

  2. Melanjutkan Sisipan di Oracle saat pengecualian muncul

  3. koneksi oci_connect gagal

  4. Memperbarui Tabel Di Oracle Jika Nilai Bidang Apa Pun Null Dan Menentukan Bahwa Pembaruan Berhasil

  5. Manfaat Mempelajari Sistem DB Baru