Ai đó có thể vui lòng giải thích các hành vi sau đây trong 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)
Ai đó có thể vui lòng giải thích các hành vi sau đây trong 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)
Câu trả lời:
<>
là tiêu chuẩn SQL-92; !=
là tương đương của nó. Cả hai đánh giá cho các giá trị, mà NULL
không -NULL
là một trình giữ chỗ để nói rằng không có giá trị.
Đó là lý do tại sao bạn chỉ có thể sử dụng IS NULL
/IS NOT NULL
làm vị ngữ cho các tình huống như vậy.
Hành vi này không dành riêng cho SQL Server. Tất cả các phương ngữ SQL tuân thủ tiêu chuẩn hoạt động theo cùng một cách.
Lưu ý : Để so sánh nếu giá trị của bạn không phải là null , bạn sử dụng IS NOT NULL
, trong khi để so sánh với giá trị không null , bạn sử dụng <> 'YOUR_VALUE'
. Tôi không thể nói nếu giá trị của tôi bằng hoặc không bằng NULL, nhưng tôi có thể nói nếu giá trị của tôi là NULL hay KHÔNG NULL. Tôi có thể so sánh nếu giá trị của tôi là một cái gì đó khác với NULL.
!=
cho đến ~ 9i như tôi hiểu, điều này mang lại rất nhiều cú pháp ANSI-92. Niềm tin của tôi là MySQL cũng tương tự, bắt đầu hỗ trợ trong 4.x.
!=
có thể đã được đưa vào một thông số kỹ thuật sau này như là một thay thế <>
. Đừng nhúng tay vào thông số kỹ thuật mới vì vậy tôi không thể nói chắc chắn.
WHERE MyColumn != NULL
hoặc WHERE MyColumn = NULL
xác định? Hay nói cách khác, nó có được đảm bảo luôn trả về 0 hàng hay không, cho dù có vô hiệu MyColumn
trong cơ sở dữ liệu hay không?
!=
chỉ đánh giá các giá trị, làm những việc như thế WHERE MyColumn != 'somevalue'
sẽ không trả về các bản ghi NULL.
NULL không có giá trị và do đó không thể so sánh bằng cách sử dụng các toán tử giá trị vô hướng.
Nói cách khác, không có giá trị nào có thể bằng (hoặc không bằng) NULL vì NULL không có giá trị.
Do đó, SQL có các vị từ IS NULL đặc biệt và IS KHÔNG NULL để xử lý NULL.
'a' != null
KHÔNG trả lại giá trị ( true
/ 1
) là phản trực quan và thỉnh thoảng lại bắt tôi ra ngoài! Tôi đã từng nghĩ "một số giá trị so với không có giá trị" sẽ luôn luôn là "không bằng", nhưng có lẽ đó chỉ là tôi?!?
SELECT * FROM MyTable WHERE coalesce(MyColumn, 'x') <> 'x'
gán hằng số nếu đó là giá trị NULL, cung cấp cho bạn một kiểu dữ liệu phù hợp cho giá trị sentinel x (trong trường hợp này là một chuỗi / char). Đây là cú pháp TSQL nhưng Oracle và các công cụ khác có các tính năng tương tự.
Lưu ý rằng hành vi này là hành vi mặc định (ANSI).
Nếu bạn:
SET ANSI_NULLS OFF
http://msdn.microsoft.com/en-us/l Library / ms188048.aspx
Bạn sẽ nhận được kết quả khác nhau.
SET ANSI_NULLS OFF
rõ ràng sẽ biến mất trong tương lai ...
create unique index UK_MyTable on MyTable (Column) where Column is not null
): msdn.microsoft.com/en-us/l Library / cc280372.aspx
SET ANSI_NULLS
TẮT, các toán tử so sánh Bằng (=) và Không bằng (<>) không tuân theo tiêu chuẩn ISO. Câu lệnh CHỌN sử dụng WHERE column_name = NULL
trả về các hàng có giá trị null trong cột_name. Một câu lệnh CHỌN sử dụng WHERE column_name <> NULL
trả về các hàng có giá trị không phải trong cột. Ngoài ra, một câu lệnh CHỌN sử dụng WHERE column_name <> XYZ_value
trả về tất cả các hàng không phải là XYZ_value và đó không phải là NULL. IMHO, tuyên bố cuối cùng này có vẻ hơi kỳ lạ trong việc loại trừ null khỏi kết quả!
Trong SQL, mọi thứ bạn đánh giá / tính toán với NULL
kết quả thành UNKNOWN
Đây là lý do tại sao SELECT * FROM MyTable WHERE MyColumn != NULL
hoặc SELECT * FROM MyTable WHERE MyColumn <> NULL
cung cấp cho bạn 0 kết quả.
Để cung cấp kiểm tra các NULL
giá trị, hàm isNull được cung cấp.
Hơn nữa, bạn có thể sử dụng IS
toán tử như bạn đã sử dụng trong truy vấn thứ ba.
Hi vọng điêu nay co ich.
Thử nghiệm duy nhất cho NULL là IS NULL hoặc IS NOT NULL. Kiểm tra sự bằng nhau là vô nghĩa bởi vì theo định nghĩa, người ta không biết giá trị là gì.
Đây là một bài viết trên wikipedia để đọc:
Chúng tôi sử dụng
SELECT * FROM MyTable WHERE ISNULL(MyColumn, ' ') = ' ';
để trả về tất cả các hàng trong đó MyColumn là NULL hoặc tất cả các hàng trong đó MyColumn là một chuỗi trống. Đối với nhiều "người dùng cuối", vấn đề NULL so với chuỗi rỗng là một sự khác biệt mà không có nhu cầu và điểm nhầm lẫn.
Tôi chỉ không thấy lý do chức năng và liền mạch cho null không thể so sánh với các giá trị khác hoặc null khác, vì chúng ta có thể so sánh rõ ràng và nói rằng chúng giống nhau hay không trong bối cảnh của chúng ta. Thật buồn cười. Chỉ vì một số kết luận hợp lý và nhất quán, chúng tôi cần phải bận tâm liên tục với nó. Nó không hoạt động, làm cho nó có nhiều chức năng hơn và để nó cho các nhà triết học và các nhà khoa học kết luận liệu nó có phù hợp hay không và nó có "logic phổ quát" hay không. :) Ai đó có thể nói rằng đó là do chỉ mục hoặc thứ gì khác, tôi nghi ngờ rằng những thứ đó không thể được tạo ra để hỗ trợ null giống như các giá trị. Nó giống như so sánh hai ly rỗng, một là ly nho và một là ly bia, chúng tôi không so sánh các loại vật thể nhưng giá trị chúng chứa, giống như bạn có thể so sánh int và varchar, với null nó ' Thậm chí còn dễ dàng hơn, không có gì và có hai điểm chung, chúng giống nhau, rõ ràng có thể so sánh với tôi và bởi những người khác viết sql, bởi vì chúng tôi liên tục phá vỡ logic đó bằng cách so sánh chúng theo những cách kỳ lạ vì một số tiêu chuẩn ANSI. Tại sao không sử dụng năng lượng máy tính để làm điều đó cho chúng tôi và tôi nghi ngờ nó sẽ làm mọi thứ chậm lại nếu mọi thứ liên quan được xây dựng với ý nghĩ đó. "Không phải là không, không có gì", nó không phải là táo, hãy đến ... Thực chất là bạn của bạn và cũng có logic ở đây. Cuối cùng, điều duy nhất quan trọng là chức năng và việc sử dụng null theo cách đó mang lại ít nhiều chức năng và dễ sử dụng. Nó có hữu ích hơn không? bởi vì chúng tôi liên tục phá vỡ logic đó bằng cách so sánh chúng theo những cách kỳ lạ vì một số tiêu chuẩn ANSI. Tại sao không sử dụng năng lượng máy tính để làm điều đó cho chúng tôi và tôi nghi ngờ nó sẽ làm mọi thứ chậm lại nếu mọi thứ liên quan được xây dựng với ý nghĩ đó. "Không phải là không, không có gì", nó không phải là táo, hãy đến ... Thực chất là bạn của bạn và cũng có logic ở đây. Cuối cùng, điều duy nhất quan trọng là chức năng và việc sử dụng null theo cách đó mang lại ít nhiều chức năng và dễ sử dụng. Nó có hữu ích hơn không? bởi vì chúng tôi liên tục phá vỡ logic đó bằng cách so sánh chúng theo những cách kỳ lạ vì một số tiêu chuẩn ANSI. Tại sao không sử dụng năng lượng máy tính để làm điều đó cho chúng tôi và tôi nghi ngờ nó sẽ làm mọi thứ chậm lại nếu mọi thứ liên quan được xây dựng với ý nghĩ đó. "Không phải là không, không có gì", nó không phải là táo, hãy đến ... Thực chất là bạn của bạn và cũng có logic ở đây. Cuối cùng, điều duy nhất quan trọng là chức năng và việc sử dụng null theo cách đó mang lại ít nhiều chức năng và dễ sử dụng. Nó có hữu ích hơn không? Không phải táo đâu là apfel, thôi nào ... Thực chất là bạn của bạn và cũng có logic ở đây. Cuối cùng, điều duy nhất quan trọng là chức năng và việc sử dụng null theo cách đó mang lại ít nhiều chức năng và dễ sử dụng. Nó có hữu ích hơn không? Không phải táo đâu là apfel, thôi nào ... Thực chất là bạn của bạn và cũng có logic ở đây. Cuối cùng, điều duy nhất quan trọng là chức năng và việc sử dụng null theo cách đó mang lại ít nhiều chức năng và dễ sử dụng. Nó có hữu ích hơn không?
Xem xét mã này:
SELECT CASE WHEN NOT (1 = null or (1 is null and null is null)) THEN 1 ELSE 0 end
Có bao nhiêu bạn biết mã này sẽ trả về cái gì? Có hoặc không có KHÔNG trả về 0. Đối với tôi đó không phải là chức năng và nó gây nhầm lẫn. Trong c #, tất cả đều như vậy, các hoạt động so sánh trả về giá trị, về mặt logic, điều này cũng tạo ra giá trị, bởi vì nếu nó không có gì để so sánh (ngoại trừ. Không có gì :)). Họ chỉ "nói": bất cứ điều gì so với null "trả về" 0 và điều đó tạo ra nhiều cách giải quyết và đau đầu.
Đây là mã đã đưa tôi đến đây:
where a != b OR (a is null and b IS not null) OR (a IS not null and b IS null)
Tôi chỉ cần so sánh nếu hai trường (trong đó) có các giá trị khác nhau, tôi có thể sử dụng hàm, nhưng ...
NULL Không thể so sánh với bất kỳ giá trị nào bằng cách sử dụng các toán tử so sánh. NULL = NULL là sai. Null không phải là một giá trị. Toán tử IS được thiết kế đặc biệt để xử lý các so sánh NULL.
null = null
nơi người ta có thể sử dụng 1=0
trong một số truy vấn đặc biệt. Và nếu họ phàn nàn, tôi đổi nó thành null != null
:)
Câu hỏi cũ, nhưng sau đây có thể cung cấp một số chi tiết hơn.
null
đại diện không có giá trị hoặc một giá trị không xác định. Nó không xác định lý do tại sao không có giá trị, có thể dẫn đến một sự mơ hồ.
Giả sử bạn chạy một truy vấn như thế này:
SELECT *
FROM orders
WHERE delivered=ordered;
nghĩa là, bạn đang tìm kiếm hàng nơi ordered
vàdelivered
ngày ngày giống nhau.
Điều gì sẽ xảy ra khi một hoặc cả hai cột là null?
Bởi vì ít nhất một trong những ngày không xác định, bạn không thể nói rằng 2 ngày giống nhau. Đây cũng là trường hợp khi cả hai ngày không xác định: làm thế nào chúng có thể giống nhau nếu chúng ta thậm chí không biết chúng là gì?
Vì lý do này, bất kỳ biểu thức nào được coi null
là giá trị đều phải thất bại. Trong trường hợp này, nó sẽ không khớp. Đây cũng là trường hợp nếu bạn thử như sau:
SELECT *
FROM orders
WHERE delivered<>ordered;
Một lần nữa, làm thế nào chúng ta có thể nói rằng hai giá trị không giống nhau nếu chúng ta không biết chúng là gì.
SQL có một bài kiểm tra cụ thể cho các giá trị bị thiếu:
IS NULL
Cụ thể nó không so sánh các giá trị, mà là tìm kiếm các giá trị còn thiếu .
Cuối cùng, liên quan đến !=
nhà điều hành, theo như tôi biết, nó không thực sự nằm trong bất kỳ tiêu chuẩn nào, nhưng nó được hỗ trợ rất rộng rãi. Nó đã được thêm vào để làm cho các lập trình viên từ một số ngôn ngữ cảm thấy thoải mái hơn ở nhà. Thành thật mà nói, nếu một lập trình viên gặp khó khăn trong việc ghi nhớ ngôn ngữ họ đang sử dụng, họ sẽ có một khởi đầu tồi tệ.
NULL
chúng ta có nghĩa là chúng ta đang so sánh một giá trị với 'có một NULL
giá trị', chứ không phải giá trị với "giá trị không xác định mà lớp lót NULL
là" nhưng chúng ta không biết ", Điều rõ ràng là chúng ta sẽ không thể biết được. Điều đó sẽ thực sự làm dịu mọi thứ lên.
IS NULL
khó hơn nhiều so với viết = NULL
. Tôi nghĩ rằng nó sẽ phù hợp hơn nếu WHERE columnA = columnB
có cách giải thích tương tự WHERE columnA = NULL
, thay vì coi trường hợp sau là trường hợp đặc biệt. Hãy nhớ rằng NULL
là không có giá trị. Trong các ngôn ngữ lập trình, nơi nó là hợp pháp để kiểm tra variable == null
nó là bởi vì null
có một ý nghĩa khác nhau; nó không đại diện cho một cái gì đó chưa biết, nhưng cố tình đặt lại một giá trị. Không như vậy với SQL.
IS NULL
AND =NULL
trong ví dụ mới nhất của bạn. Nhưng hãy xem cái cuối cùng của Hover. Tôi mệt mỏi vì phải trải qua nó nhiều lần, phải làm vô số không cần thiết? kiểm tra thêm ...
Tôi muốn đề xuất mã này tôi đã thực hiện để tìm xem có thay đổi giá trị nào không,
i
là giá trị mới và d
là cũ (mặc dù thứ tự không quan trọng). Đối với vấn đề đó, một sự thay đổi từ giá trị thành null hoặc ngược lại là một sự thay đổi nhưng từ null thành null thì không (tất nhiên, từ giá trị này sang giá trị khác là một sự thay đổi nhưng từ giá trị sang cùng một giá trị thì không).
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
Để sử dụng chức năng này, bạn có thể
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
Kết quả là:
---- 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
Việc sử dụng sql_variant làm cho nó tương thích với nhiều loại
NULL không phải là bất cứ điều gì ... không rõ. NULL không bằng bất cứ điều gì. Đó là lý do tại sao bạn phải sử dụng cụm từ ma thuật IS NULL thay vì = NULL trong các truy vấn SQL của bạn
Bạn có thể tham khảo điều này: http://weblogs.sqlteam.com/markc/archive/2009/06/08/60929.aspx
<>
trong 92 thông số kỹ thuật nhưng hầu hết các nhà cung cấp đều hỗ trợ!=
và / hoặc nó được bao gồm trong một thông số sau như 99 hoặc 03.