เหตุใด NULL = NULL จึงประเมินว่าเป็นเท็จในเซิร์ฟเวอร์ SQL


146

ในเซิร์ฟเวอร์ SQL ถ้าคุณ nullParam=NULLอยู่ในส่วนคำสั่ง where จะประเมินค่าเป็น false เสมอ นี่เป็นสิ่งที่ขัดกับความเข้าใจง่ายและทำให้ฉันมีข้อผิดพลาด ฉันเข้าใจIS NULLและIS NOT NULLคำหลักเป็นวิธีที่ถูกต้องที่จะทำ แต่ทำไมเซิร์ฟเวอร์ SQL ถึงทำงานแบบนี้?


166
ฉันไม่มีพี่สาวและไม่มีเพื่อน ถ้า "NULL = NULL" เรามีน้องสาวร่วมกันและเกี่ยวข้องกัน! :)
Matt Hamilton

11
มีข้อโต้แย้งที่ใช้เวลานานใน NULL ของ SQL (ดูตัวอย่าง: en.wikipedia.org/wiki/Null_%28SQL%29# ข้อพิพาทและfirstsql.com/inulls.htm ) ประเด็นเฉพาะที่นี่คือความเท่าเทียมกันเป็นแนวคิดทางคณิตศาสตร์ที่กำหนดมานานและ SQL ละเมิดมัน - ความเท่าเทียมกันนั้นสะท้อนกลับได้: สำหรับแต่ละ x, x = x จะต้องเป็นจริงเสมอมิฉะนั้นคนหนึ่งจะแนะนำการตีความความเท่าเทียมกันที่ไม่ได้มาตรฐานและความสับสนเป็นผลลัพธ์ที่ชัดเจน
MaD70

14
มันไม่ได้ละเมิดคณิตศาสตร์เลย ฉันคิดเลขสองตัว ฉันจะไม่บอกคุณว่าพวกเขาคืออะไร ดังนั้นตอนนี้คุณบอกฉันว่าพวกเขาเท่ากัน?
Tom H

10
@ Matt ฉันไม่เห็นด้วยกับการเปรียบเทียบของคุณ NULL = NULL ไม่ได้หมายความว่าคุณมีน้องสาวร่วมกัน แต่ก็หมายความว่าคุณทั้งคู่ไม่มีพี่สาว
reustmd

5
@ manu08 ไม่การนำไปใช้ปัจจุบัน (NULL นั้นไม่เท่ากับ NULL) หมายความว่าเราทั้งคู่ขาดน้องสาวซึ่งเป็นประเด็นของฉัน
Matt Hamilton

คำตอบ:


205

คิดว่าเป็นโมฆะเป็น "ไม่ทราบ" ในกรณีนั้น (หรือ "ไม่มีอยู่") ในกรณีใดกรณีหนึ่งคุณไม่สามารถพูดได้ว่าเท่ากันเพราะคุณไม่รู้คุณค่าของทั้งสองอย่าง ดังนั้น null = null ประเมินว่าไม่จริง (false หรือ null ขึ้นอยู่กับระบบของคุณ) เพราะคุณไม่รู้ค่าที่จะบอกว่ามันเท่ากัน ลักษณะการทำงานนี้กำหนดไว้ในมาตรฐาน ANSI SQL-92

แก้ไข: สิ่งนี้ขึ้นอยู่กับการตั้งค่าansi_nullsของคุณ ถ้าคุณปิด ANSI_NULLS สิ่งนี้จะประเมินเป็นจริง เรียกใช้รหัสต่อไปนี้เพื่อเป็นตัวอย่าง ...

set ansi_nulls off

if null = null
    print 'true'
else
    print 'false'


set ansi_nulls ON

if null = null
    print 'true'
else
    print 'false'

11
x = x เก็บจริงเมื่อ x เป็นค่าที่รู้จักกัน NULL คือการแสดงข้อความของค่าที่ไม่รู้จัก หากคุณมีค่าที่ไม่รู้จักสองค่าคุณจะไม่สามารถระบุอะไรเกี่ยวกับความเสมอภาคของพวกเขาได้ ฉันเชื่อว่าการยึดถือความจริงเป็นเวลาสองสามศตวรรษ
Dewayne Christensen

4
ตั้งแต่เดือนธันวาคมลองใช้ตัวอย่างตามฤดูกาล ฉันมีของขวัญสองชิ้นใต้ต้นไม้ ตอนนี้คุณบอกฉันว่าฉันได้สองอย่างเดียวกันหรือไม่
Dewayne Christensen

5
SQL NULL ไม่แตกต่างจาก IEEE floating point NaN ซึ่งคุณมี(NaN == NaN) == false && (NaN != Nan) == false && (NaN < NaN) == false && ...- เพราะถ้าไม่ใช่ตัวเลขคุณก็ไม่สามารถพูดอะไรได้มาก มันเป็นสิ่งที่ไม่รู้จัก แนวคิดคือเสียงแม้ว่าจะไม่ได้ใช้งานง่ายสำหรับผู้ที่ไม่เคยเห็นมาก่อน
พาเวล Minaev

8
ไม่มีการละเมิดการสะท้อนกลับที่นี่เพราะ NULL ไม่ได้เป็นสมาชิกของชุดของค่า (โดเมนในแง่เชิงสัมพันธ์) โมฆะไม่ใช่ค่า มันเป็นตัวยึดสำหรับค่าที่ไม่เป็นที่รู้จัก
พาเวล Minaev

9
เพื่อกล่าวอีกนัยหนึ่งทุกข้อNULLในนิพจน์ SQL สามารถถือว่าเป็นตัวแปรทางคณิตศาสตร์ที่แตกต่างกัน ดังนั้นการแสดงออกNULL = NULLควรได้รับการปฏิบัติเช่นเดียวกับx = yที่xและyเป็นตัวแปรที่ไม่ถูกผูกไว้ ทีนี้ถ้ามีคนถามคุณว่าอะไรคือคุณค่าของx = y? คำตอบที่สมเหตุสมผลคือ "บางคนz" ดังนั้นเราจึงมี(x = y) = z- หรือถ่ายทอดกลับไปยัง (NULL = NULL) = NULLSQL,
พาเวล Minaev

130

แฟรงค์มีอายุเท่าไหร่ ฉันไม่รู้ (เปล่า)

เชอร์ลี่ย์อายุเท่าไหร่ ฉันไม่รู้ (เปล่า)

แฟรงค์กับเชอร์ลี่ย์อายุเท่ากันหรือไม่?

คำตอบที่ถูกต้องควรเป็น "ฉันไม่รู้" (null) ไม่ใช่ "ไม่" เนื่องจากแฟรงค์และเชอร์ลี่ย์อาจมีอายุเท่ากันเราก็ไม่รู้


4
ฉันไม่เห็นด้วยว่า null เป็น "ไม่ทราบ" สิ่งที่จริงหมายถึงคือ "ไม่มีข้อมูล" อาจใช้เพื่อเป็นตัวแทนของกรณีที่ไม่ทราบข้อมูล แต่จริงๆแล้วมีแนวโน้มที่จะถูกใช้เพื่อบ่งชี้ว่ามีบางสิ่งที่ไม่มีอยู่จริง ตัวอย่างของคุณ: แฟรงก์ชื่อกลางคืออะไร? เขาไม่มี (null) ชื่อกลางของเชอร์ลี่ย์คืออะไร? เธอไม่มี (null) แฟรงค์กับเชอร์ลี่ย์มีชื่อกลางเหมือนกันหรือไม่? ใช่? ไม่มี? ไม่ทราบเหรอ ฉันสามารถดูอาร์กิวเมนต์สำหรับ "ไม่" และฉันสามารถดูอาร์กิวเมนต์สำหรับ "ไม่รู้" แต่ไม่มีอาร์กิวเมนต์จริงสำหรับ "ใช่" เว้นแต่คุณจะเป็นตัวอักษรมากเกินไป
Richiban

2
@richiban ฉันไม่เห็นด้วย การขาดการมีอยู่ของแถวหมายถึง 'ไม่มีข้อมูล'
Neil McGuigan

1
@NeilMcGuigan เป็นเรื่องจริงหากข้อมูลมีตารางของตัวเอง แต่ข้อมูลที่แสดงในคอลัมน์เป็นอย่างไร คุณจะไม่ใช้ 'null' เพื่อแสดงว่าไม่มีข้อมูลหรือไม่ 'ไม่เป็นที่รู้จัก' เป็นเหตุผลที่เฉพาะเจาะจงมากสำหรับข้อมูลที่ไม่มีอยู่
Richiban

3
แต่null = nullอัตราผลตอบแทนไม่ได้FALSE NULL
slartidan

1
@slartidan ฉันเห็นด้วยกับคุณ แต่มันไม่ถูกต้อง
Neil McGuigan

28

ที่นี่ฉันหวังว่าจะชี้แจงตำแหน่งของฉัน

NULL = NULLประเมินว่าFALSEผิด แฮ็กเกอร์และ Mister NULLตอบได้อย่างถูกต้อง นี่คือเหตุผล Dewayne Christensen เขียนถึงฉันในความคิดเห็นที่Scott Ivey :

ตั้งแต่เดือนธันวาคมลองใช้ตัวอย่างตามฤดูกาล ฉันมีของขวัญสองชิ้นใต้ต้นไม้ ตอนนี้คุณบอกฉันว่าฉันได้สองอย่างเดียวกันหรือไม่

พวกเขาอาจจะแตกต่างกันหรือพวกเขาจะเท่ากันคุณไม่รู้จนกว่าจะเปิดของขวัญทั้งสอง ใครจะรู้? คุณเชิญคนสองคนที่ไม่รู้จักซึ่งกันและกันและทั้งคู่ได้ทำของขวัญให้กับคุณ - หายาก แต่ไม่ใช่เป็นไปไม่ได้§ §

ดังนั้นคำถาม: UNKNOWN สองรายการนี้นำเสนอเหมือนกัน (เท่ากับ =) หรือไม่ คำตอบที่ถูกต้องคือ: UNKNOWN (เช่นNULL)

ตัวอย่างนี้มีจุดประสงค์เพื่อแสดงให้เห็นว่า ".. (falseหรือnullขึ้นอยู่กับระบบของคุณ) .. " เป็นคำตอบที่ถูกต้อง - ไม่เพียง แต่ NULLถูกต้องใน 3VL (หรือไม่เป็นไรที่คุณจะยอมรับระบบที่ให้คำตอบที่ผิด) )

คำตอบที่ถูกต้องสำหรับคำถามนี้ต้องเน้นสองประเด็นนี้:

  • ตรรกะสามค่า (3VL) เป็นเรื่องง่าย (ดูคำถามอื่น ๆ อีกมากมายในหัวข้อนี้ใน Stackoverflow และในฟอรัมอื่นเพื่อให้แน่ใจ);
  • DBMS ที่ใช้ SQL มักจะไม่เคารพแม้แต่ 3VL พวกเขาให้คำตอบที่ผิดบางครั้ง (เช่นการยืนยันโปสเตอร์ดั้งเดิม, SQL Server ทำในกรณีนี้)

ดังนั้นฉันจึงย้ำ: SQL ไม่ได้บังคับให้แปลความหมายของความเท่าเทียมซึ่งเป็นสิ่งที่ดี:

for any x, x = x §§ (ในภาษาอังกฤษธรรมดา: ไม่ว่าเอกภพแห่งวาทกรรมอะไรจะเป็น "สิ่ง" เสมอไป )

.. ใน 3VL A ( TRUE, FALSE, NULL) ความคาดหวังของผู้คนจะสอดคล้องกับ 2VL ( TRUE, FALSEซึ่งแม้ใน SQL จะใช้ได้สำหรับค่าอื่น ๆ ทั้งหมด) เช่นx = x ประเมินเสมอ TRUEสำหรับค่าใด ๆ เป็นไปได้ของ x - ไม่มีข้อยกเว้น

โปรดทราบว่า NULL นั้นถูกต้อง " ไม่ใช่ค่าที่ " ที่ (เนื่องจากคำขอโทษของพวกเขาแสร้งทำเป็นว่า) เป็นสิ่งที่เราสามารถกำหนดให้เป็นค่าแอตทริบิวต์ (??) เป็นส่วนหนึ่งของตัวแปรความสัมพันธ์ ดังนั้นจึงเป็นค่าที่ยอมรับได้ของทุกประเภท (โดเมน) ไม่เพียง แต่ประเภทของการแสดงออกทางตรรกะ

และนี่คือจุดของฉัน : NULLตามตัวอักษรคือ "สัตว์ประหลาด" ฉันชอบพูดว่า:ไร้สาระเรื่องไร้สาระ

ฉันคิดว่าสูตรนี้ชัดเจนกว่าและเป็นที่ถกเถียงกันน้อยกว่า - ขอโทษสำหรับความสามารถด้านภาษาอังกฤษของฉัน

นี่เป็นเพียงหนึ่งในปัญหาของ NULLs ดีกว่าที่จะหลีกเลี่ยงพวกเขาทั้งหมดเมื่อเป็นไปได้

§เรามีความกังวลเกี่ยวกับคุณค่าที่นี่ดังนั้นความจริงที่ว่าของขวัญทั้งสองมักเป็นวัตถุทางกายภาพที่แตกต่างกันสองรายการไม่ใช่การคัดค้านที่ถูกต้อง ถ้าคุณไม่มั่นใจฉันขอโทษที่นี่ไม่ใช่สถานที่ที่จะอธิบายความแตกต่างระหว่างค่าและความหมาย "วัตถุ" (พีชคณิตเชิงสัมพันธ์มีค่าความหมายจากจุดเริ่มต้น - ดูหลักการข้อมูลของ Codd ฉันคิดว่าผู้ใช้ SQL DBMS don ไม่สนใจเกี่ยวกับความหมายทั่วไป)

§§ความรู้ของฉันนี้เป็นความจริงที่ยอมรับ (ในรูปแบบหรืออื่น แต่ตีความเสมอใน 2VL ก) มาตั้งแต่สมัยโบราณและที่ว่าเพราะใช้งานง่ายเพื่อให้ 3VLs (เป็นตระกูลของ logics ในความเป็นจริง) เป็นการพัฒนาเมื่อเร็ว ๆ นี้ (แต่ฉันไม่แน่ใจว่าเมื่อไหร่ที่ถูกพัฒนาขึ้นครั้งแรก)

บันทึก Side:ถ้ามีคนจะแนะนำล่าง , หน่วยและตัวเลือกประเภทเป็นความพยายามในการที่จะปรับ SQL NULLs ผมจะเชื่อเฉพาะหลังจากการตรวจสอบรายละเอียดค่อนข้างที่จะแสดงให้เห็นถึงวิธีการใช้งาน SQL กับ NULLs มีระบบประเภทเสียงและจะชี้แจงในที่สุด NULL ใด ("ค่าที่ไม่ได้ค่อนข้างคุ้มค่า") เหล่านี้คืออะไรจริงๆ


ในสิ่งที่ติดตามฉันจะพูดผู้เขียนบางคน ข้อผิดพลาดหรือการละเว้นอาจเป็นของฉันและไม่ใช่ของผู้เขียนต้นฉบับ

Joe Celko บน SQL NULLs

ฉันเห็น Joe Celko มักอ้างถึงในฟอรัมนี้ เห็นได้ชัดว่าเขาเป็นนักเขียนที่เคารพนับถือมากที่นี่ ดังนั้นฉันจึงพูดกับตัวเองว่า: "เขาเขียนอะไรเกี่ยวกับ SQL NULLs เขาอธิบายปัญหา NULLs ได้อย่างไร" หนึ่งในเพื่อนของฉันมีSQL ebook ของJoe Celko สำหรับ smartiesรุ่น ebook การเขียนโปรแกรม SQL ขั้นสูงรุ่นที่ 3ขั้นสูงรุ่นที่ มาดูกัน.

ก่อนสารบัญ สิ่งที่ทำให้ฉันประทับใจมากที่สุดคือจำนวนครั้งที่ NULL ถูกกล่าวถึงและในบริบทที่หลากหลายที่สุด:

3.4 เลขคณิตและ NULLs 109
3.5 การแปลงค่าไปยังและจาก NULL 110
3.5.1 NULLIF () ฟังก์ชัน 110
6 NULLs: ข้อมูลที่ขาดหายไปใน SQL 185
6.4 การเปรียบเทียบ NULLs 190
6.5 NULLs และตรรกะ 190
6.5.1 NULLS ในแบบสอบถามย่อย 191
6.5.2 มาตรฐาน โซลูชัน SQL 193
6.6 คณิตศาสตร์และ NULLs 193
6.7 ฟังก์ชันและ NULLs 193
6.8 NULL และภาษาโฮสต์ 194
6.9 คำแนะนำการออกแบบสำหรับ NULLs 195
6.9.1 หลีกเลี่ยง NULLs จากโปรแกรมโฮสต์ 197
6.10 หมายเหตุเกี่ยวกับค่า NULL หลายค่า 198
10.1 IS NULL Predicate 241
10.1 1 แหล่งที่มาของ NULLs 242
...

และอื่น ๆ มันดัง "กรณีพิเศษที่น่ารังเกียจ" ให้ฉัน

ฉันจะเข้าไปดูบางส่วนของหนังสือเหล่านี้พร้อมข้อความที่ตัดตอนมาจากหนังสือเล่มนี้พยายาม จำกัด ตัวเองให้จำเป็นสำหรับเหตุผลด้านลิขสิทธิ์ ฉันคิดว่าคำพูดเหล่านี้ตกอยู่ในหลักคำสอน "การใช้อย่างเป็นธรรม" และพวกเขาสามารถกระตุ้นให้ซื้อหนังสือได้ - ดังนั้นฉันหวังว่าจะไม่มีใครบ่นได้ นอกจากนี้ฉันจะละเว้นจากการรายงานข้อมูลโค้ดด้วยเหตุผลเดียวกัน ขอโทษด้วยกับเรื่องนั้น. ซื้อหนังสือเพื่ออ่านเหตุผลเกี่ยวกับการบันทึกข้อมูล

หมายเลขหน้าระหว่างวงเล็บในสิ่งที่ตามมา

ข้อ จำกัด ไม่เป็นโมฆะ (11)

ข้อ จำกัด ของคอลัมน์ที่สำคัญที่สุดคือ NOT NULL ซึ่งห้ามการใช้ NULL ในคอลัมน์ ใช้ข้อ จำกัด นี้เป็นประจำและลบออกเมื่อคุณมีเหตุผลที่ดีเท่านั้น มันจะช่วยให้คุณหลีกเลี่ยงภาวะแทรกซ้อนของค่า NULLเมื่อคุณทำการสอบถามกับข้อมูล

มันไม่ได้เป็นค่า ; มันเป็นเครื่องหมายที่ถือสถานที่ที่ค่าอาจไป

อีกครั้ง "ค่านี้ แต่ไม่ค่อนข้างค่า" ไร้สาระ ที่เหลือดูเหมือนจะสมเหตุสมผลสำหรับฉัน

(12)

กล่าวโดยย่อ NULL ทำให้เกิดคุณสมบัติที่ผิดปกติจำนวนมากใน SQL ซึ่งเราจะกล่าวถึงในภายหลัง ทางออกที่ดีที่สุดของคุณคือการจดจำสถานการณ์และกฎของ NULL เมื่อคุณไม่สามารถหลีกเลี่ยงได้

เรื่องของ SQL, NULL และอนันต์:

(104) บทที่ 3: ข้อมูลตัวเลขใน SQL

SQL ไม่ยอมรับโมเดล IEEE สำหรับคณิตศาสตร์ด้วยเหตุผลหลายประการ

...

หากกฎ IEEE สำหรับคณิตศาสตร์ได้รับอนุญาตใน SQL เราจะต้องใช้กฎการแปลงประเภทสำหรับอนันต์และวิธีการแสดงค่าตัวเลขที่แน่นอนหลังจากการแปลง ผู้คนมีปัญหากับ NULL มากพอดังนั้นอย่าไปที่นั่น

การปรับใช้ SQL ที่ไม่ได้ตัดสินใจเกี่ยวกับความหมายของ NULL ในบริบทเฉพาะ:

3.6.2 ฟังก์ชันเลขชี้กำลัง (116)

ปัญหาคือลอการิทึมจะไม่ได้กำหนดเมื่อ (x <= 0) การใช้ SQL บางตัวส่งคืนข้อความแสดงข้อผิดพลาดบางคนส่งคืนNULLและ DB2 / 400 เวอร์ชัน 3 รีลีส 1 ส่งคืน * NEGINF (ย่อมาจาก“ infinity เชิงลบ”) ตามผลลัพธ์

Joe Celko อ้างถึง David McGoveran และ CJ Date:

6 NULLs: ไม่มีข้อมูลใน SQL (185)

ในหนังสือของพวกเขาA Guide to Sybase และ SQL Server David McGoveran และ CJ Date กล่าวว่า“ มันเป็นความเห็นของนักเขียนคนนี้มากกว่า NULLs อย่างน้อยที่กำหนดไว้ในปัจจุบันและนำไปใช้ใน SQL นั้นมีปัญหามากกว่าที่ควรและควรหลีกเลี่ยง พวกเขาแสดงพฤติกรรมที่แปลกและไม่สอดคล้องกันมากและอาจเป็นแหล่งที่มาของข้อผิดพลาดและความสับสน (โปรดทราบว่าความคิดเห็นและการวิพากษ์วิจารณ์เหล่านี้ใช้กับระบบใด ๆ ที่สนับสนุน NULL แบบ SQL ไม่ใช่เฉพาะกับ SQL Server โดยเฉพาะ)”

NULLs เป็นการติดยา :

(186/187)

ในส่วนที่เหลือของหนังสือเล่มนี้ฉันจะแนะนำให้คุณไม่ใช้พวกเขาซึ่งอาจดูขัดแย้ง แต่ไม่ใช่ คิดว่าเป็นโมฆะเป็นยาเสพติด; ใช้อย่างถูกต้องและใช้งานได้สำหรับคุณ แต่ใช้งานในทางที่ผิดและสามารถทำลายทุกสิ่งได้ นโยบายที่ดีที่สุดของคุณคือการหลีกเลี่ยงค่า NULL เมื่อคุณสามารถและใช้อย่างถูกต้องเมื่อคุณต้องการ

ข้อคัดค้านที่ไม่ซ้ำกันของฉันคือการ "ใช้อย่างถูกต้อง" ซึ่งโต้ตอบกับพฤติกรรมการใช้งานที่ไม่ดี

6.5.1 NULLS ในภาคย่อยแบบสอบถาม (191/192)

คนลืมว่าแบบสอบถามย่อยมักจะซ่อนการเปรียบเทียบกับ NULL พิจารณาสองตารางนี้:

...

ผลลัพธ์จะว่างเปล่า นี่คือcounterintuitiveแต่ถูกต้อง

(คั่น)

6.5.2 โซลูชัน SQL มาตรฐาน (193)

SQL-92 แก้ไขปัญหา 3VL (ตรรกะสามค่า) บางส่วนโดยการเพิ่มเพรดิเคตใหม่ของแบบฟอร์ม:

<เงื่อนไขการค้นหา> คือ [ไม่ใช่] TRUE | เท็จ UNKNOWN

แต่ UNKNOWN เป็นแหล่งของปัญหาในตัวของมันเองดังนั้น CJ Date ในหนังสือของเขาที่อ้างถึงด้านล่างจึงแนะนำอีกครั้งในบทที่4.5 หลีกเลี่ยง Nulls ใน SQL :

  • อย่าใช้คำว่าไม่รู้จักไม่ว่าในกรณีใด ๆ

อ่าน"ASIDE"บน UNKNOWN และลิงก์ด้านล่าง

6.8 NULLs และภาษาโฮสต์ (194)

อย่างไรก็ตามคุณควรรู้ว่าจะจัดการ NULL อย่างไรเมื่อต้องผ่านไปยังโปรแกรมโฮสต์ ไม่มีภาษาโฮสต์มาตรฐานที่กำหนดการฝังรองรับ NULL ซึ่งเป็นอีกเหตุผลที่ดีที่จะหลีกเลี่ยงการใช้ใน schema ฐานข้อมูลของคุณ

(คั่น)

6.9 คำแนะนำการออกแบบสำหรับ NULLs (195)

มันเป็นความคิดที่ดีที่จะประกาศตารางฐานทั้งหมดของคุณด้วยข้อ จำกัด ไม่เป็นโมฆะในทุกคอลัมน์เมื่อทำได้ NULLs สร้างความสับสนให้กับคนที่ไม่รู้จัก SQL และค่า NULL นั้นมีราคาแพง

การคัดค้าน: NULLs สร้างความสับสนแม้กระทั่งผู้ที่รู้จัก SQL เป็นอย่างดีดูด้านล่าง

(195)

ควรหลีกเลี่ยงค่า NULL ในคีย์ต่างประเทศ SQL ช่วยให้ความสัมพันธ์นี้ "ประโยชน์ของข้อสงสัย" แต่อาจทำให้ข้อมูลสูญหายในการสืบค้นที่เกี่ยวข้องกับการรวม ตัวอย่างเช่นกำหนดรหัสหมายเลขชิ้นส่วนในสินค้าคงคลังที่อ้างถึงเป็นคีย์ต่างประเทศโดยตารางคำสั่งซื้อคุณจะมีปัญหาในการรับรายชื่อของชิ้นส่วนที่มีค่า NULL นี่คือความสัมพันธ์ที่บังคับ; คุณไม่สามารถสั่งซื้อชิ้นส่วนที่ไม่มีอยู่ได้

(คั่น)

6.9.1 หลีกเลี่ยง NULL จากโปรแกรมโฮสต์ (197)

คุณสามารถหลีกเลี่ยงการใส่ NULL ลงในฐานข้อมูลจากโปรแกรมโฮสต์ด้วยวินัยการเขียนโปรแกรมบางอย่าง

...

  1. กำหนดผลกระทบของข้อมูลที่หายไปในการเขียนโปรแกรมและการรายงาน: คอลัมน์ตัวเลขที่มีค่า NULL เป็นปัญหาเนื่องจากแบบสอบถามที่ใช้ฟังก์ชันการรวมสามารถให้ผลลัพธ์ที่ทำให้เข้าใจผิด

(คั่น)

(227)

SUM () ของชุดว่างเปล่าเป็น NULL เสมอ หนึ่งในข้อผิดพลาดทั่วไปของการเขียนโปรแกรมที่เกิดขึ้นเมื่อใช้เคล็ดลับนี้คือการเขียนเคียวรีที่อาจส่งคืนมากกว่าหนึ่งแถว หากคุณไม่ได้คิดคุณอาจเขียนตัวอย่างสุดท้ายเป็น: ...

(คั่น)

10.1.1 แหล่งที่มาของ NULLs (242)

เป็นสิ่งสำคัญที่ต้องจำตำแหน่งที่ NULL สามารถเกิดขึ้นได้ พวกเขาเป็นมากกว่าเพียงแค่ค่าที่เป็นไปในคอลัมน์ ฟังก์ชันการรวมในชุดว่าง, OUTER JOIN, นิพจน์ทางคณิตศาสตร์ที่มี NULLs, และตัวดำเนินการ OLAP ส่งคืน NULL ทั้งหมด โครงสร้างเหล่านี้มักปรากฏเป็นคอลัมน์ใน VIEW

(คั่น)

(301)

พบปัญหาอื่นของ NULL เมื่อคุณพยายามแปลง IN predicates เป็น EXISTS predicates

(คั่น)

16.3 ฟังก์ชั่นการเพรดิเคตและ Extrema (313)

ในตอนแรกมันเป็นเรื่องธรรมดาที่ทั้งสองเพรดิเคตนั้นไม่เหมือนกันใน SQL:

...

แต่คุณต้องจำกฎสำหรับฟังก์ชั่น extrema - พวกมันดรอป NULL ทั้งหมดก่อนที่จะคืนค่าที่มากกว่าหรือน้อยกว่า เพรดิเคต ALL จะไม่ปล่อย NULL ดังนั้นคุณสามารถรับได้ในผลลัพธ์

(คั่น)

(315)

อย่างไรก็ตามความหมายในมาตรฐานจะถูกเขียนในเชิงลบเพื่อให้ NULL ได้รับประโยชน์จากข้อสงสัย ...

อย่างที่คุณเห็นมันเป็นความคิดที่ดีที่จะหลีกเลี่ยง NULL ในข้อ จำกัด ที่ไม่เหมือนใคร

การสนทนากลุ่มตาม:

NULL ได้รับการปฏิบัติราวกับว่าพวกเขาทุกคนเท่าเทียมกันและจัดตั้งกลุ่มของตัวเอง แต่ละกลุ่มจะถูกลดขนาดเป็นแถวเดียวในตารางผลลัพธ์ใหม่ที่แทนที่กลุ่มเก่า

ซึ่งหมายความว่าสำหรับ GROUP BY clause NULL = NULL ไม่ได้ประเมินเป็น NULL เช่นเดียวกับใน 3VL แต่จะประเมินเป็น TRUE

มาตรฐาน SQL สับสน:

คำสั่งซื้อและค่า NULL (329)

ไม่ว่าจะเป็นค่าคีย์การเรียงลำดับที่เป็นโมฆะถือว่ามากกว่าหรือน้อยกว่าค่าที่ไม่เป็นโมฆะคือการกำหนดใช้งาน แต่ ...

... มีผลิตภัณฑ์ SQL ที่ใช้วิธีใดวิธีหนึ่ง

ในเดือนมีนาคมปี 1999 คริสฟาร์รานำขึ้นคำถามจากหนึ่งในนักพัฒนาของเขาว่าทำให้เขาต้องตรวจสอบส่วนหนึ่งของมาตรฐาน SQL ที่ฉันคิดว่าฉันเข้าใจ คริสพบความแตกต่างระหว่างความเข้าใจทั่วไปและถ้อยคำที่เกิดขึ้นจริงของสเปค

และอื่น ๆ ฉันคิดว่าเพียงพอโดย Celko

CJ Date บน SQL NULLs

CJ Date มีความรุนแรงมากขึ้นเกี่ยวกับ NULLs: หลีกเลี่ยง NULL ใน SQL ระยะเวลา ในความเป็นจริงบทที่ 4 ของSQL และทฤษฎีเชิงสัมพันธ์ของเขา: วิธีการเขียนรหัส SQL ที่ถูกต้องมีชื่อว่า "NO DUPLICATES, NO NULLS" พร้อมกับบทย่อย "4.4 มีอะไรผิดปกติกับ Nulls" และ "4.5 การหลีกเลี่ยงค่า Null ใน SQL" (ไปตามลิงก์: ขอบคุณ Google หนังสือคุณสามารถอ่านหน้าออนไลน์ได้บางหน้า)

Fabian Pascal บน SQL NULLs

จากปัญหาการปฏิบัติในการจัดการฐานข้อมูล - การอ้างอิงสำหรับผู้ประกอบการคิด (ไม่มีข้อความที่ตัดตอนมาขอโทษออนไลน์):

10.3 ผลกระทบเชิง Pratical

10.3.1 SQL NULLs

... SQL ทนทุกข์ทรมานจากปัญหาที่เกิดขึ้นใน 3VL เช่นเดียวกับจากนิสัยใจคอ, ความยุ่งเหยิง, การต่อต้านการตอบโต้และข้อผิดพลาดทันที [10, 11]; ในหมู่พวกเขามีดังต่อไปนี้:

  • ฟังก์ชันการรวม (เช่น SUM (), AVG ()) จะละเว้นค่า NULL (ยกเว้น COUNT ())
  • นิพจน์สเกลาร์บนตารางที่ไม่มีแถวจะประเมินค่าเป็น NULL ไม่ถูกต้องแทนที่จะเป็น 0
  • นิพจน์ "NULL = NULL" ประเมินเป็น NULL แต่จริง ๆ แล้วไม่ถูกต้องใน SQL ORDER BY ถือว่า NULL เท่ากัน (สิ่งที่พวกเขานำหน้าหรือติดตามค่า "ปกติ" จะถูกปล่อยให้ผู้ขาย DBMS)
  • นิพจน์ "x IS NOT NULL" ไม่เท่ากับ "NOT (x IS NULL)" เช่นเดียวกับในกรณี 2VL

...

ทั้งหมดดำเนินการในเชิงพาณิชย์ภาษา SQL ตามนี้วิธี 3VL และจึงไม่เพียง แต่พวกเขา exibits ปัญหาเหล่านี้ แต่พวกเขายังมีปัญหาการใช้ spefic ซึ่งแตกต่างกันไปในผลิตภัณฑ์


4
"และนี่คือประเด็นของฉัน: NULL ตามตัวอักษรคือ" สัตว์ประหลาด " - นั่นเป็นเพราะNULLไม่ใช่ค่า
พาเวล Minaev

1
นอกจากนี้ SQL Server (NULL = NULL) -> FALSEไม่ได้ให้ ในการอ้างถึงเอกสารประกอบสำหรับANSI_NULLS: "เมื่อระบุ ON การเปรียบเทียบทั้งหมดกับค่า Null จะประเมินเป็นUNKNOWNเมื่อระบุ OFF การเปรียบเทียบค่าที่ไม่ใช่ UNICODE กับค่า NULL จะเป็น TRUE หากค่าทั้งสองเป็น NULL"
Pavel Minaev

@Pavel Minaev: a) และ TRUE นั้นดีกว่า FALSE อย่างไร b) หากไม่ใช่ค่าเหตุใดจึงกำหนดให้เป็นส่วนหนึ่งของค่าตัวแปร
MaD70

1
>> เนื่องจากเป็นเดือนธันวาคมลองใช้ตัวอย่างตามฤดูกาล ฉันมีของขวัญสองชิ้นใต้ต้นไม้ ตอนนี้คุณบอกฉันว่าฉันได้สองอย่างเดียวกันหรือไม่ ..... ใช่คุณทำอย่างที่คุณได้รับสองสิ่งและเท่าที่คุณกังวลตอนนี้เท่าที่คุณมีความรู้ในปัจจุบันพวกเขาจะเหมือนกับคุณ
Brad Thomas

3
null = null ควรเป็นจริง null เป็นค่าซึ่งอาจจะดีที่กำหนดแทนไม่รู้จักค่า แต่ก็ยังอาจหมายถึงขาดของค่า มันควรจะขึ้นอยู่กับนักพัฒนาที่จะตัดสินใจว่า null หมายถึงอะไร แต่ตัว null นั้นเป็นค่าจริงและ null เป็น null = null การใช้งานอื่น ๆ นั้นถูกห้อมล้อมด้วยหายนะเนื่องจากคุณแทรกซึมตรรกะแบบไตรภาคลงในเพรดิเคตซึ่งเป็นบูลีนพื้นฐาน ฉันตกใจว่านี่เป็นการถาวรในการตั้งค่าในเซิร์ฟเวอร์ SQL OFF OFF OFF กับมัน
Triynko


9

เพียงเพราะคุณไม่รู้ว่าสองสิ่งคืออะไรไม่ได้หมายความว่ามันเท่ากัน ถ้าเมื่อคุณคิดว่าNULLคุณคิดว่า "NULL" (สตริง) คุณอาจต้องการทดสอบความเท่าเทียมกันที่แตกต่างกันเช่น Postgresql's IS DISTINCT FROMANDIS NOT DISTINCT FROM

จากเอกสาร PostgreSQL ใน"ฟังก์ชั่นการเปรียบเทียบและตัวดำเนินการ"

การIS DISTINCT FROMแสดงออกการแสดงออก

การIS NOT DISTINCT FROMแสดงออกการแสดงออก

สำหรับอินพุตที่ไม่มีค่า null IS DISTINCT FROMจะเหมือนกับตัว<>ดำเนินการ อย่างไรก็ตามถ้าทั้งสองอินพุตเป็นโมฆะมันจะคืนค่าเป็นเท็จและถ้ามีเพียงอินพุตเดียวเท่านั้นที่เป็นโมฆะมันจะคืนค่าเป็นจริง ในทำนองเดียวกันIS NOT DISTINCT FROMก็เหมือนกับ=สำหรับอินพุตที่ไม่เป็นโมฆะ แต่จะส่งกลับค่าจริงเมื่ออินพุตทั้งสองเป็นโมฆะและเท็จเมื่ออินพุตเพียงหนึ่งรายการเป็นโมฆะ ดังนั้นโครงสร้างเหล่านี้ทำหน้าที่ได้อย่างมีประสิทธิภาพราวกับว่า null เป็นค่าข้อมูลปกติมากกว่า "ไม่ทราบ"


5

แนวคิดของ NULL เป็นที่น่าสงสัยในการพูดน้อยที่สุด Codd แนะนำโมเดลเชิงสัมพันธ์และแนวคิดของ NULL ในบริบท (และนำเสนอมากกว่าหนึ่งชนิดของ NULL!) อย่างไรก็ตามทฤษฎีเชิงสัมพันธ์ได้วิวัฒนาการมาตั้งแต่งานเขียนดั้งเดิมของ Codd: ข้อเสนอบางส่วนของเขาถูกทิ้ง (เช่นคีย์หลัก) และคนอื่น ๆ ไม่เคยติด (เช่นผู้ประกอบการ theta) ในทฤษฎีความสัมพันธ์สมัยใหม่ (ทฤษฎีความสัมพันธ์ที่แท้จริงฉันควรเน้น) เป็นโมฆะก็ไม่มีอยู่จริง ดูประกาศที่สาม http://www.thethirdmanifesto.com/

ภาษา SQL ประสบปัญหาความเข้ากันได้ย้อนหลัง NULL พบวิธีเข้าสู่ SQL และเราติดอยู่กับมัน การใช้งานNULLใน SQL นั้นมีข้อบกพร่อง (การดำเนินการของ SQL Server ทำให้สิ่งต่าง ๆ มีความซับซ้อนมากขึ้นANSI_NULLSตัวเลือก)

ฉันแนะนำให้หลีกเลี่ยงการใช้คอลัมน์ NULLable ในตารางฐาน


แม้ว่าบางทีฉันไม่ควรถูกล่อลวง แต่ฉันแค่ต้องการยืนยันการแก้ไขของฉันเองเกี่ยวกับวิธีการNULLทำงานใน SQL:

NULL= ประเมินNULLUNKNOWN

UNKNOWN เป็นค่าตรรกะ

NULL เป็นค่าข้อมูล

ง่ายต่อการพิสูจน์เช่น

SELECT NULL = NULL

สร้างข้อผิดพลาดใน SQL Server อย่างถูกต้อง หากผลลัพธ์นั้นเป็นค่าข้อมูลเราก็คาดหวังที่จะเห็นNULLเพราะคำตอบบางอย่าง (ผิดพลาด) แนะนำให้เราทำ

ค่าโลจิคัลUNKNOWNจะถือว่าแตกต่างกันใน SQL DML และ SQL DDL ตามลำดับ

ใน SQL DML UNKNOWNทำให้แถวถูกลบจาก resultset

ตัวอย่างเช่น:

CREATE TABLE MyTable
(
 key_col INTEGER NOT NULL UNIQUE, 
 data_col INTEGER
 CHECK (data_col = 55)
);

INSERT INTO MyTable (key_col, data_col)
   VALUES (1, NULL);

INSERTประสบความสำเร็จแถวนี้แม้ว่าสภาพหายไปCHECK NULL = NULLนี่เป็นเพราะกำหนดไว้ในมาตรฐาน SQL-92 ("ANSI"):

คำจำกัดความของตาราง 11.6

3)

หากข้อ จำกัด ตารางเป็นคำจำกัดความการตรวจสอบให้ SC เป็นเงื่อนไขการค้นหาที่มีอยู่ในคำจำกัดความการตรวจสอบทันทีและให้ T เป็นชื่อตารางที่รวมอยู่ในตัวบอกข้อ จำกัด ตารางที่สอดคล้องกัน; ข้อ จำกัด ของตารางไม่พอใจถ้าหาก

มีอยู่ (เลือก * จาก T ที่ไม่มี (SC))

เป็นความจริง.

อ่านอีกครั้งอย่างระมัดระวังตามตรรกะ

ในภาษาอังกฤษแบบธรรมดาแถวใหม่ของเราด้านบนจะได้รับ 'ประโยชน์ของข้อสงสัย' เกี่ยวกับการเป็น UNKNOWNและได้รับอนุญาตให้ผ่าน

ใน SQL DML กฎสำหรับWHEREclause นั้นง่ายต่อการติดตามมากขึ้น:

เงื่อนไขการค้นหาจะถูกนำไปใช้กับแต่ละแถวของ T ผลลัพธ์ของคำสั่งย่อยคือตารางของแถวเหล่านั้นของ T ซึ่งผลลัพธ์ของเงื่อนไขการค้นหาเป็นจริง

ในภาษาอังกฤษแบบธรรมดาแถวที่ประเมินจะUNKNOWNถูกลบออกจาก resultset


5

ที่technetมีคำอธิบายที่ดีเกี่ยวกับการทำงานของค่า Null

Null หมายถึงไม่ทราบ

ดังนั้นการแสดงออกบูลีน

value = null

ไม่ได้ประเมินว่าเป็นเท็จ แต่จะประเมินเป็นโมฆะ แต่ถ้านั่นเป็นผลลัพธ์สุดท้ายของคำสั่งย่อย where จะไม่มีการส่งคืนสิ่งใด นั่นเป็นวิธีที่ใช้งานได้จริงเนื่องจากการคืนค่า null จะเป็นการยากที่จะเข้าใจ

มันน่าสนใจและสำคัญมากจะเข้าใจสิ่งต่อไปนี้:

หากในแบบสอบถามเรามี

where (value=@param Or @param is null) And id=@anotherParam

และ

  • ค่า = 1
  • @param เป็นโมฆะ
  • id = 123
  • @ anotherParam = 123

แล้วก็

"value = @ param" ประเมินเป็นโมฆะ
"@param เป็นโมฆะ" ประเมินเป็นจริง
"id = @ anotherParam" ประเมินเป็นจริง

ดังนั้นการแสดงออกที่จะประเมินกลายเป็น

(null หรือจริง) และจริง

เราอาจถูกล่อลวงให้คิดว่าที่นี่ "โมฆะหรือจริง" จะถูกประเมินเป็นโมฆะดังนั้นการแสดงออกทั้งหมดกลายเป็นโมฆะและแถวจะไม่ถูกส่งกลับ

ไม่เป็นเช่นนั้น ทำไม?

เนื่องจาก "null หรือ true" ประเมินว่าเป็นจริงซึ่งมีเหตุผลมากเนื่องจากถ้าตัวถูกดำเนินการหนึ่งเป็นจริงกับ Or-operator ดังนั้นไม่ว่าค่าของตัวถูกดำเนินการอื่นจะไม่ส่งกลับค่าจริง ดังนั้นจึงไม่สำคัญว่าตัวถูกดำเนินการอื่นจะไม่รู้จัก (null)

ดังนั้นเราจึงมีจริง = จริงและดังนั้นแถวจะถูกส่งกลับ

หมายเหตุ: ด้วยตรรกะที่ใสเหมือนกันซึ่ง "null หรือจริง" ประเมินเป็นจริง "null และจริง" ประเมินเป็น null

อัปเดต:
โอเคเพื่อให้เสร็จสมบูรณ์ฉันต้องการเพิ่มส่วนที่เหลือที่นี่ด้วยซึ่งค่อนข้างสนุกเมื่อเทียบกับข้างต้น

"โมฆะหรือเท็จ" ประเมินเป็นโมฆะ "โมฆะและเท็จ" ประเมินเป็นเท็จ :)

แน่นอนว่าตรรกะนั้นยังคงชัดเจนในตัวเองเหมือนเมื่อก่อน


4

เพราะNULLหมายถึง 'ค่าที่ไม่รู้จัก' และค่าที่ไม่รู้จักสองค่าไม่เท่ากัน

ดังนั้นหากตรรกะของเราNULLN ° 1 เท่ากับNULLN ° 2 เราก็ต้องบอกว่าอย่างใด:

SELECT 1
WHERE ISNULL(nullParam1, -1) = ISNULL(nullParam2, -1)

ที่ทราบค่า-1N ° 1 เท่ากับ-1N ° 2


nullParam1 = -1และnullParam2 =NULLและเครื่องบินขัดข้อง .... ควรจะเป็นISNULL(NULLIF(@nullParam1, @nullParam2), NULLIF(@nullParam2, nullParam1)) IS NULL
Selvin

4

คำตอบที่นี่ดูเหมือนจะมาจากมุมมอง CS ดังนั้นฉันต้องการเพิ่มจากมุมมองของนักพัฒนา

สำหรับนักพัฒนา NULL มีประโยชน์มาก คำตอบที่นี่บอกว่าเป็นโมฆะหมายถึงไม่ทราบและบางทีในทฤษฎี CS ที่เป็นจริงจำไม่ได้มันอยู่พักหนึ่ง ในการพัฒนาจริงอย่างน้อยในประสบการณ์ของฉันที่เกิดขึ้นประมาณ 1% ของเวลา อีก 99% จะใช้สำหรับกรณีที่ค่าไม่ได้เป็นที่รู้จัก แต่เป็นที่รู้จักกันว่าจะถูกยกเลิก

ตัวอย่างเช่น:

  • Client.LastPurchaseสำหรับลูกค้าใหม่ ยังไม่เป็นที่ทราบแน่ชัดว่าเขายังไม่ได้ทำการซื้อ

  • เมื่อใช้ ORM ที่มีตารางต่อการทำแผนที่ลำดับชั้นของคลาส ค่าบางค่าจะไม่ถูกแมปสำหรับคลาสที่แน่นอน

  • เมื่อทำการแมปโครงสร้างแบบทรีรูทมักจะมีParent = NULL

  • และอื่น ๆ อีกมากมาย...

ฉันแน่ใจว่านักพัฒนาส่วนใหญ่ในบางจุดเขียนWHERE value = NULLไม่ได้รับผลลัพธ์ใด ๆ และนั่นคือวิธีที่พวกเขาเรียนรู้เกี่ยวกับIS NULLไวยากรณ์ เพียงดูว่ามีผู้โหวตกี่คนสำหรับคำถามนี้และคำถามที่เชื่อมโยงกัน

ฐานข้อมูล SQL เป็นเครื่องมือและควรออกแบบวิธีที่ง่ายที่สุดสำหรับผู้ใช้ในการทำความเข้าใจ


1
ดูเหมือนว่าทุกคนจะตะโกนว่า "ไม่ทราบค่า NULL" และปรับพฤติกรรมให้เหมาะสม ใช่ถ้านั่นคือหลักฐานแล้ว 3VL อาจเป็นคำตอบ แต่ในฐานข้อมูลเกือบทั้งหมดที่ฉันทำงานอยู่ NULL หมายถึงไม่อยู่ ขออภัยเสียงของคุณหายไปในถิ่นทุรกันดาร @AlexDev
John Rees

3

NULL ไม่เท่ากับอะไรเลยแม้แต่ตัวเอง โซลูชันส่วนบุคคลของฉันเพื่อทำความเข้าใจพฤติกรรมของ NULL คือหลีกเลี่ยงการใช้มากที่สุด :)


1
รวมทั้งอาจจะเท่ากับทุกอย่างที่มันเป็นในกรณีของซ้าย / ขวา / นอกร่วม ...
มิเกลเวนทูรา

5
ช่างเป็นคำตอบที่ไร้ประสิทธิภาพ เช่นเดียวกันกับเด็กระดับประถมเกี่ยวกับพีชคณิต แต่โดยไม่ได้รับรู้จริง ๆ ว่าอะไรที่พยายามจะแก้มันก็แค่หลุดออกมาอย่างโง่ ๆ ซึ่งมันทำ
Evan Carroll

2
@Evan: จริง ๆ แล้วการหลีกเลี่ยง NULL เป็นโซลูชันเสียง ลอจิกที่มีค่า 3 ไม่ได้ไม่มีข้อโต้แย้งและหลายคนรู้สึกว่า SQL จะดีกว่าถ้าไม่มี NULL และความซับซ้อน (จำเป็น) ทั้งหมดที่เกี่ยวข้อง
sleske

3
"คนจำนวนมาก" เป็นคำพังพอนและ "ไม่ขัดแย้ง" เป็นวิธีการปกปิด "แย้ง" ที่ง่ายกว่าซึ่ง 3VL ไม่ใช่
Evan Carroll

"NULL ไม่เท่ากับอะไรเลยแม้แต่ตัวมันเอง" ไปตามตรรกะนั้น <somevalue>! = NULL ควรกลับมาจริง ในเอกภพที่แปลกประหลาดของ SQL อย่างไรก็ตามมันผิดพลาด
Tom Lint

3

คำถาม: มี
ใครไม่รู้จักไม่เท่ากับอีกไม่รู้จัก?
(NULL = NULL)
คำถามนั้นเป็นสิ่งที่ไม่มีใครสามารถตอบได้ดังนั้นจึงมีค่าเริ่มต้นเป็นจริงหรือเท็จขึ้นอยู่กับการตั้งค่า ansi_nulls ของคุณ

อย่างไรก็ตามคำถาม:
ตัวแปรนี้ไม่ทราบแน่ชัดหรือไม่?
คำถามนี้แตกต่างกันมากและสามารถตอบได้จริง

nullVariable = null กำลังเปรียบเทียบค่า
nullVariable คือ null กำลังเปรียบเทียบสถานะของตัวแปร


3

ความสับสนที่เกิดจากระดับของความร้าย (นามธรรม) ที่มาจากการใช้เกี่ยวกับการเป็นโมฆะ

กลับไปที่ "สิ่งที่อยู่ใต้ต้นคริสต์มาส" เปรียบเทียบ "ไม่ทราบ" อธิบายสถานะของความรู้เกี่ยวกับสิ่งที่อยู่ในกล่อง A

ดังนั้นหากคุณไม่ทราบว่าสิ่งที่อยู่ในกล่องที่คุณพูดมัน "ไม่ทราบ" แต่นั่นไม่ได้หมายความว่า "ไม่รู้จัก" ที่อยู่ภายในกล่อง มีสิ่งอื่นที่ไม่รู้จักอยู่ในกล่องอาจมีวัตถุบางอย่างหรือไม่มีอะไรในกล่อง

ในทำนองเดียวกันหากคุณไม่ทราบว่ามีอะไรในกล่อง B คุณสามารถติดป้ายสถานะความรู้ของคุณเกี่ยวกับเนื้อหาว่าเป็น "ไม่ทราบ"

ดังนั้นนี่คือนักเตะ: สถานะความรู้ของคุณเกี่ยวกับ Box A เท่ากับสถานะความรู้ของคุณเกี่ยวกับ Box BB (สถานะความรู้ของคุณในทั้งสองกรณีคือ "ไม่ทราบ" หรือ "ฉันไม่รู้ว่ามีอะไรในกล่อง") แต่เนื้อหาของกล่องอาจจะเท่ากันหรืออาจจะไม่เท่ากัน

กลับไปที่ SQL คุณควรจะสามารถเปรียบเทียบค่าเมื่อคุณรู้ว่ามันคืออะไร น่าเสียดายที่ฉลากที่อธิบายถึงการขาดความรู้ถูกเก็บไว้ในเซลล์ดังนั้นเราจึงถูกล่อลวงให้ใช้มันเป็นค่า แต่เราไม่ควรใช้สิ่งนั้นเป็นค่าเพราะมันจะนำไปสู่ ​​"เนื้อหาของ Box A เท่ากับเนื้อหาของ Box B เมื่อเราไม่รู้ว่ามีอะไรใน Box A และ / หรือเราไม่รู้ว่ามีอะไรใน Box B (เชิงเหตุผลความหมาย "ถ้าฉันไม่รู้ว่ามีอะไรในกล่อง A และถ้าฉันไม่รู้ว่ามีอะไรในกล่อง B แสดงว่ามีอะไรในกล่อง A = มีอะไรในกล่อง B" เป็นเท็จ)

ยายม้าที่ตายแล้ว


3

MSDN มีบทความอธิบายที่ดีเกี่ยวกับ nulls และตรรกะสามสถานะที่เกิดขึ้น

กล่าวโดยย่อข้อมูลจำเพาะ SQL92 กำหนด NULL ว่าไม่รู้จักและ NULL ที่ใช้ในตัวดำเนินการต่อไปนี้ทำให้เกิดผลลัพธ์ที่ไม่คาดคิดสำหรับการเริ่มต้น:

= operator NULL   true   false 
NULL       NULL   NULL   NULL
true       NULL   true   false
false      NULL   false  true

and op     NULL   true   false 
NULL       NULL   NULL   false
true       NULL   true   false
false      false  false  false

or op      NULL   true   false 
NULL       NULL   true   NULL
true       true   true   true
false      NULL   true   false

แต่คำถามไม่ได้เกี่ยวกับ 3VL (ตรรกะสามค่า) เป็นเรื่องเกี่ยวกับคุณสมบัติการสะท้อนของความเท่าเทียมกัน
MaD70

จะมีความแม่นยำมากขึ้นในที่สุดเมื่อฉันอธิบายรายละเอียดในคำตอบของฉันปัญหาเกิดขึ้นเมื่อมีการตีความความเท่าเทียมกันใน 3VL เพื่อให้สมบัติสะท้อนของความเท่าเทียมไม่ได้ประเมินว่าเป็นจริงเสมอไป
MaD70

1

null ไม่เป็นที่รู้จักใน sql ดังนั้นเราจึงไม่สามารถคาดหวังสอง unknowns ให้เหมือนกันได้

อย่างไรก็ตามคุณสามารถรับพฤติกรรมนั้นได้โดยการตั้งค่า ANSI_NULLS เป็น Off (เปิดโดยค่าเริ่มต้น) คุณจะสามารถใช้ตัวดำเนินการ = สำหรับค่า Null ได้

SET ANSI_NULLS off
if null=null
print 1
else 
print 2
set ansi_nulls on
if null=null
print 1
else 
print 2

2
ทั้งหมดนี้เป็นชนิดของไม่มี โลกมีคำจำกัดความของnullเรียนรู้ที่จะเข้าใจหรือเพียงแค่เปลี่ยนตารางให้มีประเภท int และปรับปรุงคอลัมน์
Evan Carroll

3
ฉันไม่แนะนำให้ปิด SET ANSI_NULLS จริงๆ ฉันค้นพบ ANSI_NULLS เกี่ยวกับวิธีที่ยาก แต่ก็เป็นเรื่องดีเสมอที่จะรู้ว่าตัวเลือกทั้งหมดที่มีอยู่เป็นพิเศษเมื่อคุณเจอบรรทัดที่ระบุ Where SomeId = null คุณจะเข้าใจบรรทัดนั้นอย่างไรโดยไม่ทราบเกี่ยวกับ ANSI_NULLS วิธีที่ฉันดูโพสต์ของฉันมีประโยชน์ .. :)
ps

1

คุณทำงานให้กับรัฐบาลที่ลงทะเบียนข้อมูลเกี่ยวกับพลเมือง ซึ่งรวมถึงรหัสประจำตัวสำหรับทุกคนในประเทศ เด็กถูกทิ้งไว้ที่ประตูโบสถ์เมื่อ 40 ปีก่อนไม่มีใครรู้ว่าพ่อแม่ของพวกเขาเป็นใคร พ่อของบุคคลนี้ ID NULLเป็น คนสองคนนั้นมีอยู่จริง นับคนที่ใช้รหัสพ่อเดียวกันกับคนอื่นอย่างน้อยหนึ่งคน (คนที่เป็นพี่น้อง) คุณนับสองคนนี้ด้วยหรือไม่

คำตอบคือไม่คุณไม่เพราะเราไม่รู้ว่าพวกเขาเป็นพี่น้องหรือไม่

สมมติว่าคุณไม่มีNULLตัวเลือกและใช้ค่าที่กำหนดไว้ล่วงหน้าเพื่อเป็นตัวแทนของ "ไม่ทราบ" บางทีอาจเป็นสตริงว่างหรือตัวเลข 0 หรืออักขระ * เป็นต้นจากนั้นคุณจะมีคำสั่งที่ * = * , 0 = 0, และ“” =“” ฯลฯ นี่ไม่ใช่สิ่งที่คุณต้องการ (ตามตัวอย่างด้านบน) และตามที่คุณมักจะลืมเกี่ยวกับกรณีเหล่านี้ (ตัวอย่างด้านบนเป็นกรณีที่ชัดเจนนอกกรอบความคิดทั่วไปทุกวัน ) จากนั้นคุณต้องใช้ภาษาที่จะจำสำหรับคุณที่NULL = NULLไม่เป็นความจริง

ความจำเป็นเป็นแม่ของการประดิษฐ์


0

นอกเหนือจากคำตอบที่ยอดเยี่ยมอื่น ๆ :

AND: The result of true and unknown is unknown, false and unknown is false,
while unknown and unknown is unknown.

OR: The result of true or unknown is true, false or unknown is unknown, while unknown or unknown is unknown.

NOT: The result of not unknown is unknown

0

หากคุณกำลังมองหานิพจน์ที่คืนค่าจริงสำหรับ NULL สองตัวคุณสามารถใช้:

SELECT 1 
WHERE EXISTS (
    SELECT NULL
    INTERSECT
    SELECT NULL
)

มันจะมีประโยชน์ถ้าคุณต้องการที่จะทำซ้ำข้อมูลจากตารางหนึ่งไปยังอีก


0

ตัวอย่างเช่นการทดสอบความเท่าเทียมกันในคำสั่งกรณีเมื่อประโยคสามารถเปลี่ยนแปลงได้

XYZ = NULL 

ถึง

XYZ IS NULL

ถ้าฉันต้องการรักษาช่องว่างและสตริงว่างเท่ากับ NULL ฉันมักจะใช้การทดสอบความเท่าเทียมกันเช่น:

(NULLIF(ltrim( XYZ ),'') IS NULL)
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.