มีคนช่วยอธิบายพฤติกรรมต่อไปนี้ใน SQL ได้ไหม?
SELECT * FROM MyTable WHERE MyColumn != NULL (0 Results)
SELECT * FROM MyTable WHERE MyColumn <> NULL (0 Results)
SELECT * FROM MyTable WHERE MyColumn IS NOT NULL (568 Results)
มีคนช่วยอธิบายพฤติกรรมต่อไปนี้ใน SQL ได้ไหม?
SELECT * FROM MyTable WHERE MyColumn != NULL (0 Results)
SELECT * FROM MyTable WHERE MyColumn <> NULL (0 Results)
SELECT * FROM MyTable WHERE MyColumn IS NOT NULL (568 Results)
คำตอบ:
<>
คือมาตรฐาน SQL-92 !=
มันเทียบเท่า ทั้งสองประเมินค่าซึ่งNULL
ไม่ได้NULL
เป็นตัวยึดตำแหน่งที่จะบอกว่าไม่มีค่า
นี่คือเหตุผลที่คุณสามารถใช้IS NULL
/ IS NOT NULL
เป็นเพรดิเคตสำหรับสถานการณ์ดังกล่าวเท่านั้น
ลักษณะการทำงานนี้ไม่เฉพาะ SQL Server ภาษา SQL ที่สอดคล้องกับมาตรฐานทั้งหมดทำงานในลักษณะเดียวกัน
หมายเหตุ : เพื่อเปรียบเทียบถ้าค่าไม่เป็นโมฆะคุณสามารถใช้IS NOT NULL
ในขณะที่เปรียบเทียบกับไม่เป็นโมฆะ<> 'YOUR_VALUE'
ค่าที่คุณใช้ ฉันไม่สามารถบอกได้ว่าค่าของฉันเท่ากับหรือไม่เท่ากับ NULL แต่ฉันสามารถพูดได้ว่าค่าของฉันเป็น NULL หรือไม่ NULL ฉันสามารถเปรียบเทียบได้ว่าค่าของฉันเป็นอย่างอื่นที่ไม่ใช่ NULL หรือไม่
!=
จนกระทั่ง ~ 9i ตามที่ฉันเข้าใจซึ่งทำให้เกิดไวยากรณ์ ANSI-92 จำนวนมาก ความเชื่อของฉันคือ MySQL นั้นคล้ายกันเริ่มสนับสนุนใน 4.x
!=
<>
ไม่มีมือของฉันในรายละเอียดใหม่ดังนั้นฉันไม่สามารถพูดได้อย่างแน่นอน
WHERE MyColumn != NULL
หรือWHERE MyColumn = NULL
กำหนดขึ้น? หรือกล่าวอีกนัยหนึ่งคือมันรับประกันว่าจะส่งคืน 0 แถวเสมอไม่ว่าMyColumn
จะเป็นโมฆะในฐานข้อมูลหรือไม่
!=
ประเมินเฉพาะค่าการทำบางสิ่งเช่นWHERE MyColumn != 'somevalue'
จะไม่ส่งคืนระเบียน NULL
NULL ไม่มีค่าดังนั้นจึงไม่สามารถเปรียบเทียบได้โดยใช้ตัวดำเนินการค่าสเกลาร์
กล่าวอีกนัยหนึ่งไม่มีค่าใดสามารถเท่ากับ (หรือไม่เท่ากับ) NULL เนื่องจาก NULL ไม่มีค่า
ดังนั้น SQL จึงมีค่าพิเศษคือ NULL และไม่ใช่ NULL predicates สำหรับจัดการกับ NULL
'a' != null
ไม่ส่งคืนค่า ( true
/ 1
) เป็นตัวนับที่ใช้งานง่ายและจับฉันออกเป็นครั้งคราว! ฉันเคยคิดว่า "คุณค่าบางอย่างเมื่อเทียบกับไม่มีค่า" มักจะเป็น "ไม่เท่ากัน" แต่อาจเป็นเพียงฉันนั่น?
SELECT * FROM MyTable WHERE coalesce(MyColumn, 'x') <> 'x'
กำหนดค่าคงที่ถ้าเป็นค่า NULL โดยให้คุณกำหนดประเภทข้อมูลที่เหมาะสมสำหรับค่า Sentinel x (ในกรณีนี้คือสตริง / ถ่าน) นี่คือไวยากรณ์ TSQL แต่ Oracle และเอ็นจิ้นอื่นมีคุณสมบัติที่คล้ายกัน
โปรดทราบว่าพฤติกรรมนี้เป็นพฤติกรรมเริ่มต้น (ANSI)
ถ้าคุณ:
SET ANSI_NULLS OFF
http://msdn.microsoft.com/en-us/library/ms188048.aspx
คุณจะได้รับผลลัพธ์ที่แตกต่าง
SET ANSI_NULLS OFF
ดูเหมือนจะหายไปในอนาคต ...
create unique index UK_MyTable on MyTable (Column) where Column is not null
): msdn.microsoft.com/en-us/library/cc280372.aspx
SET ANSI_NULLS
ปิดการทำงานตัวดำเนินการเปรียบเทียบ Equals (=) และ Not Equal To (<>) จะไม่เป็นไปตามมาตรฐาน ISO คำสั่ง SELECT ที่ใช้WHERE column_name = NULL
ส่งคืนแถวที่มีค่า Null ใน column_name คำสั่ง SELECT ที่ใช้WHERE column_name <> NULL
ส่งคืนแถวที่มีค่าไม่เป็นศูนย์ในคอลัมน์ นอกจากนี้คำสั่ง SELECT ที่ใช้WHERE column_name <> XYZ_value
ส่งคืนแถวทั้งหมดที่ไม่ใช่ XYZ_value และไม่ใช่ NULL IMHO ข้อความล่าสุดนี้ดูแปลก ๆ เล็กน้อยในการยกเว้นค่า null จากผลลัพธ์!
ใน SQL ทุกสิ่งที่คุณประเมิน / คำนวณด้วยNULL
ผลลัพธ์ใน UNKNOWN
นี่คือสาเหตุSELECT * FROM MyTable WHERE MyColumn != NULL
หรือSELECT * FROM MyTable WHERE MyColumn <> NULL
ให้ผลลัพธ์ 0 รายการแก่คุณ
เพื่อให้การตรวจสอบNULL
ค่าฟังก์ชั่น isNull มีให้
นอกจากนี้คุณสามารถใช้IS
โอเปอเรเตอร์ตามที่คุณใช้ในคิวรีที่สาม
หวังว่านี่จะช่วยได้
การทดสอบเพียงอย่างเดียวสำหรับ NULL คือ NULL หรือไม่ NULL การทดสอบความเท่าเทียมกันนั้นเป็นเรื่องไร้สาระเพราะตามนิยามแล้วเราไม่ทราบว่าค่าคืออะไร
นี่คือบทความวิกิพีเดียที่จะอ่าน:
เราใช้
SELECT * FROM MyTable WHERE ISNULL(MyColumn, ' ') = ' ';
เพื่อกลับแถวทั้งหมดที่ MyColumn เป็น NULL หรือแถวทั้งหมดที่ MyColumn เป็นสตริงว่าง สำหรับหลาย ๆ คน "ผู้ใช้" ปัญหา NULL เทียบกับสตริงว่างคือความแตกต่างโดยไม่จำเป็นต้องและจุดของความสับสน
ฉันไม่เห็นเหตุผลเชิงหน้าที่และไร้รอยต่อสำหรับโมฆะที่ไม่สามารถเทียบได้กับค่าอื่น ๆ หรือโมฆะอื่น ๆ ทำให้เราสามารถเปรียบเทียบได้อย่างชัดเจนและบอกว่าพวกเขาเหมือนกันหรือไม่ในบริบทของเรา มันสนุกมาก. เพียงเพราะข้อสรุปเชิงตรรกะและความมั่นคงบางประการเราจำเป็นต้องกังวลอยู่ตลอดเวลาด้วย มันใช้งานไม่ได้ทำให้ใช้งานได้มากกว่าและทิ้งไว้ให้กับนักปรัชญาและนักวิทยาศาสตร์เพื่อสรุปว่ามันสอดคล้องหรือไม่และมันถือ "ตรรกะสากล" :) บางคนอาจบอกว่าเป็นเพราะดัชนีหรืออย่างอื่นฉันสงสัยว่าสิ่งเหล่านั้นไม่สามารถทำได้เพื่อสนับสนุนค่า null เช่นเดียวกับค่า มันเหมือนกับการเปรียบเทียบแก้วเปล่าสองอันอันหนึ่งคือแก้วเถาวัลย์และอีกแก้วเป็นเบียร์เราไม่ได้เปรียบเทียบประเภทของวัตถุ แต่มีค่าเช่นเดียวกับที่คุณสามารถเปรียบเทียบ int และ varchar กับ null ได้ ' ง่ายกว่ามันไม่มีอะไรและไม่มีอะไรสองอย่างที่เหมือนกันพวกมันเหมือนกันอย่างชัดเจนเทียบเคียงได้กับฉันและคนอื่น ๆ ที่เขียน sql เพราะเรามักจะผิดตรรกะนั้นโดยการเปรียบเทียบพวกมันด้วยวิธีแปลก ๆ เพราะมาตรฐาน ANSI บางอย่าง ทำไมไม่ใช้พลังคอมพิวเตอร์ทำเพื่อเราและฉันสงสัยว่ามันจะช้าลงหากทุกอย่างที่เกี่ยวข้องกับการสร้างขึ้นในใจ "มันไม่ได้เป็นโมฆะไม่มีอะไรเลย" ไม่ใช่แอปเปิ้ลเป็น apfel มา ... ฟังก์ชั่นคือเพื่อนของคุณและมันก็มีเหตุผลที่นี่ ในที่สุดสิ่งเดียวที่สำคัญก็คือฟังก์ชั่นการใช้งานและการใช้ nulls ในทางที่นำมาซึ่งการทำงานมากขึ้นและน้อยลงและใช้งานง่าย มันมีประโยชน์มากกว่านี้ไหม? เพราะเรามักจะทำลายตรรกะนั้นอย่างต่อเนื่องโดยการเปรียบเทียบพวกมันด้วยวิธีแปลก ๆ เพราะมาตรฐาน ANSI บางอย่าง ทำไมไม่ใช้พลังคอมพิวเตอร์ทำเพื่อเราและฉันสงสัยว่ามันจะช้าลงหากทุกอย่างที่เกี่ยวข้องกับการสร้างขึ้นในใจ "มันไม่ได้เป็นโมฆะไม่มีอะไรเลย" ไม่ใช่แอปเปิ้ลเป็น apfel มา ... ฟังก์ชั่นคือเพื่อนของคุณและมันก็มีเหตุผลที่นี่ ในที่สุดสิ่งเดียวที่สำคัญก็คือฟังก์ชั่นการใช้งานและการใช้ nulls ในทางที่นำมาซึ่งการทำงานมากขึ้นและน้อยลงและใช้งานง่าย มันมีประโยชน์มากกว่านี้ไหม? เพราะเรามักจะทำลายตรรกะนั้นอย่างต่อเนื่องโดยการเปรียบเทียบพวกมันด้วยวิธีแปลก ๆ เพราะมาตรฐาน ANSI บางอย่าง ทำไมไม่ใช้พลังคอมพิวเตอร์ทำเพื่อเราและฉันสงสัยว่ามันจะช้าลงหากทุกอย่างที่เกี่ยวข้องกับการสร้างขึ้นในใจ "มันไม่ได้เป็นโมฆะไม่มีอะไรเลย" ไม่ใช่แอปเปิ้ลเป็น apfel มา ... ฟังก์ชั่นคือเพื่อนของคุณและมันก็มีเหตุผลที่นี่ ในที่สุดสิ่งเดียวที่สำคัญก็คือฟังก์ชั่นการใช้งานและการใช้ nulls ในทางที่นำมาซึ่งการทำงานมากขึ้นและน้อยลงและใช้งานง่าย มันมีประโยชน์มากกว่านี้ไหม? ไม่แอปเปิ้ลมันเป็น apfel มา ... ฟังก์ชั่นเป็นเพื่อนของคุณและยังมีตรรกะที่นี่ ในที่สุดสิ่งเดียวที่สำคัญก็คือฟังก์ชั่นการใช้งานและการใช้ nulls ในทางที่นำมาซึ่งการทำงานมากขึ้นและน้อยลงและใช้งานง่าย มันมีประโยชน์มากกว่านี้ไหม? ไม่แอปเปิ้ลมันเป็น apfel มา ... ฟังก์ชั่นเป็นเพื่อนของคุณและยังมีตรรกะที่นี่ ในที่สุดสิ่งเดียวที่สำคัญก็คือฟังก์ชั่นการใช้งานและการใช้ nulls ในทางที่นำการทำงานมากขึ้นและน้อยลงและใช้งานง่าย มันมีประโยชน์มากกว่านี้ไหม?
พิจารณารหัสนี้:
SELECT CASE WHEN NOT (1 = null or (1 is null and null is null)) THEN 1 ELSE 0 end
มีกี่คนที่รู้ว่ารหัสนี้จะส่งคืนอย่างไร ไม่ว่าจะมีหรือไม่มีก็ให้ผลตอบแทน 0 สำหรับฉันที่ใช้งานไม่ได้และมันสับสน ใน c # มันคือทั้งหมดที่มันควรจะเป็นคือการเปรียบเทียบการดำเนินการส่งคืนค่าตรรกะเหตุผลนี้ก็สร้างมูลค่าเพราะถ้ามันไม่ได้มีอะไรที่จะเปรียบเทียบ (ยกเว้น. ไม่มีอะไร :)) พวกเขาเพียงแค่ "พูดว่า": สิ่งใดก็ตามที่เปรียบเทียบกับ null "จะส่งคืน" 0 และนั่นทำให้เกิดการแก้ไขปัญหาและปวดหัวจำนวนมาก
นี่คือรหัสที่นำมาให้ฉันที่นี่:
where a != b OR (a is null and b IS not null) OR (a IS not null and b IS null)
ฉันแค่ต้องเปรียบเทียบว่าสองฟิลด์ (ในที่) มีค่าที่แตกต่างกันฉันสามารถใช้ฟังก์ชั่น แต่ ...
NULL ไม่สามารถเปรียบเทียบกับค่าใด ๆ ได้โดยใช้ตัวดำเนินการเปรียบเทียบ NULL = NULL เป็นเท็จ Null ไม่ใช่ค่า ผู้ประกอบการ IS ได้รับการออกแบบมาเป็นพิเศษเพื่อจัดการการเปรียบเทียบค่า NULL
null = null
ที่ที่อาจใช้1=0
ในการสอบถามเฉพาะกิจ และถ้าพวกเขาบ่นผมเปลี่ยนไปnull != null
:)
คำถามเก่า แต่ต่อไปนี้อาจให้รายละเอียดเพิ่มเติมบางอย่าง
null
แทนค่าหรือค่าที่ไม่รู้จัก ไม่ได้ระบุสาเหตุที่ไม่มีค่าซึ่งอาจนำไปสู่ความคลุมเครือบางอย่าง
สมมติว่าคุณเรียกใช้แบบสอบถามเช่นนี้:
SELECT *
FROM orders
WHERE delivered=ordered;
นั่นคือคุณกำลังมองหาแถวที่ordered
และdelivered
วันที่เหมือนกัน
จะต้องเกิดอะไรขึ้นเมื่อหนึ่งหรือทั้งสองคอลัมน์เป็นโมฆะ
เนื่องจากไม่ทราบวันที่อย่างน้อยหนึ่งวันคุณไม่สามารถคาดหวังได้ว่าวันที่ 2 จะเหมือนกัน นี่เป็นกรณีที่ไม่ทราบวันที่ทั้งสอง : พวกเขาจะเหมือนกันได้อย่างไรถ้าเราไม่รู้ด้วยซ้ำว่ามันคืออะไร?
ด้วยเหตุนี้การแสดงออกใด ๆ ที่ถือว่าnull
เป็นค่าจะต้องล้มเหลว ในกรณีนี้มันจะไม่ตรงกัน นี่เป็นกรณีนี้หากคุณลองทำสิ่งต่อไปนี้:
SELECT *
FROM orders
WHERE delivered<>ordered;
อีกครั้งเราจะพูดได้อย่างไรว่าสองค่านั้นไม่เหมือนกันถ้าเราไม่รู้ว่ามันคืออะไร
SQL มีการทดสอบเฉพาะสำหรับค่าที่หายไป:
IS NULL
โดยเฉพาะมันไม่ได้เป็นการเปรียบเทียบค่า แต่มันจะหาค่าที่ขาดหายไป
ในที่สุดเกี่ยวกับ!=
ผู้ประกอบการเท่าที่ฉันรู้ว่ามันไม่ได้อยู่ในมาตรฐานใด ๆ แต่ได้รับการสนับสนุนอย่างกว้างขวางมาก มีการเพิ่มเพื่อให้โปรแกรมเมอร์จากบางภาษารู้สึกเหมือนอยู่บ้าน ตรงไปตรงมาหากโปรแกรมเมอร์มีปัญหาในการจำภาษาที่ใช้อยู่พวกเขาจะเริ่มต้นไม่ดี
NULL
เราหมายถึงว่าเรากำลังเปรียบเทียบค่ากับ 'มีNULL
ค่า' ไม่ใช่ค่าที่เป็น "ค่าที่ไม่ได้ระบุว่าการ underlaying NULL
นั้นมี แต่เราไม่รู้ "ซึ่งเห็นได้ชัดว่าเราไม่สามารถรู้ได้ นั่นจะทำให้สิ่งต่าง ๆ ง่ายขึ้น
IS NULL
นั้นยากกว่าการเขียน= NULL
มากนัก ฉันคิดว่ามันจะสอดคล้องกันมากขึ้นหากWHERE columnA = columnB
มีการตีความแบบเดียวกันWHERE columnA = NULL
มากกว่าจะถือว่าเป็นกรณีพิเศษ โปรดจำไว้ว่าNULL
เป็นไม่ได้ค่า ในการเขียนโปรแกรมภาษาที่มันเป็นถูกต้องตามกฎหมายในการทดสอบvariable == null
ก็คงเป็นเพราะnull
มีความหมายที่แตกต่างกัน มันไม่ได้เป็นตัวแทนของสิ่งที่ไม่รู้จัก แต่เป็นการรีเซ็ตค่าโดยเจตนา ไม่เช่นนั้นกับ SQL
IS NULL
และ=NULL
ในตัวอย่างล่าสุดของคุณ แต่ลองดูที่อันสุดท้ายของโฮเวอร์ ฉันเบื่อที่จะประสบกับมันซ้ำแล้วซ้ำอีกโดยไม่จำเป็นต้องทำอะไรมากมาย? การตรวจสอบเป็นพิเศษ ...
ฉันอยากจะแนะนำรหัสนี้ฉันทำเพื่อค้นหาว่ามีการเปลี่ยนแปลงในค่าเป็นค่า
i
ใหม่และd
เก่า (แม้ว่าคำสั่งไม่สำคัญ) สำหรับเรื่องนั้นการเปลี่ยนแปลงจากค่าเป็นโมฆะหรือในทางกลับกันคือการเปลี่ยนแปลง แต่จากโมฆะเป็นโมฆะไม่ได้ (แน่นอนจากมูลค่าเป็นค่าอื่นเป็นการเปลี่ยนแปลง แต่จากมูลค่าเป็นเหมือนกันไม่ใช่)
CREATE FUNCTION [dbo].[ufn_equal_with_nulls]
(
@i sql_variant,
@d sql_variant
)
RETURNS bit
AS
BEGIN
DECLARE @in bit = 0, @dn bit = 0
if @i is null set @in = 1
if @d is null set @dn = 1
if @in <> @dn
return 0
if @in = 1 and @dn = 1
return 1
if @in = 0 and @dn = 0 and @i = @d
return 1
return 0
END
ในการใช้ฟังก์ชั่นนี้คุณสามารถ
declare @tmp table (a int, b int)
insert into @tmp values
(1,1),
(1,2),
(1,null),
(null,1),
(null,null)
---- in select ----
select *, [dbo].[ufn_equal_with_nulls](a,b) as [=] from @tmp
---- where equal ----
select *,'equal' as [Predicate] from @tmp where [dbo].[ufn_equal_with_nulls](a,b) = 1
---- where not equal ----
select *,'not equal' as [Predicate] from @tmp where [dbo].[ufn_equal_with_nulls](a,b) = 0
ผลลัพธ์ที่ได้คือ:
---- in select ----
a b =
1 1 1
1 2 0
1 NULL 0
NULL 1 0
NULL NULL 1
---- where equal ----
1 1 equal
NULL NULL equal
---- where not equal ----
1 2 not equal
1 NULL not equal
NULL 1 not equal
การใช้ sql_variant ทำให้สามารถใช้งานได้หลากหลายประเภท
NULL ไม่ใช่อะไรเลย ... ไม่เป็นที่รู้จัก ค่า NULL ไม่เท่ากัน นั่นคือเหตุผลที่คุณต้องใช้วลีมหัศจรรย์ IS NULL แทน = NULL ในคิวรี SQL ของคุณ
คุณสามารถอ้างถึงสิ่งนี้: http://weblogs.sqlteam.com/markc/archive/2009/06/08/60929.aspx
<>
ที่อยู่ในสเปค 92 แต่ส่วนใหญ่ผู้ให้บริการสนับสนุน!=
และ / หรือมันจะรวมอยู่ในสเป็คในภายหลังเช่น 99 หรือ 03