[英]How to do equality comparison in SQL with C#-like behavior?
How to compare equality of value in SQL with null? 如何比较SQL中的值的等价与null?
For those familiar with C#, here are the results of comparing nullable values: 对于熟悉C#的人,以下是比较可空值的结果:
null == null : true
null == john : false
null == paul : false
john == null : false
john == john : true
john == paul : false
paul == null : false
paul == john : false
paul == paul : true
The easiest solution I found in SQL is to coalesced the nullable fields into some sentinel value(eg 'scoobydoo') then compare them 我在SQL中找到的最简单的解决方案是将可空字段合并为一些sentinel值(例如'scoobydoo')然后比较它们
coalesce(A, 'scoobydoo') = coalesce(B, 'scoobydoo')
But that is plain kludge if somebody uses the sentinel value, if A happens to be NULL and B is 'scoobydoo', then the expression above would yield true 但是,如果有人使用sentinel值,那么这就是普通的kludge,如果A恰好是NULL而B是'scoobydoo',那么上面的表达式会产生真值
This is exactly my purpose on asking for the logic of the code above (T-SQL UPDATE trigger): 这正是我要求上面代码逻辑的目的(T-SQL UPDATE触发器):
-- detect if the value changes
if (select invoice_date from inserted) <>
(select invoice_date from deleted) begin
-- do something to summary tables here
end
How to do equality comparison in SQL with C#-like behavior? 如何在SQL中使用类似C#的行为进行等式比较?
[EDIT: Found the answer here ] [编辑:在这里找到答案]
Tested the code (Postgres nice boolean support, FTW!): 测试了代码(Postgres很好的布尔支持,FTW!):
select
A, B,
A = B,
A IS NOT DISTINCT FROM B, -- "logically" same as above
A <> B,
A IS DISTINCT FROM B -- "logically" same as above
from(
values
(null, null),
(null, 'john'),
(null, 'paul'),
('john', null),
('john', 'john'),
('john', 'paul'),
('paul', null),
('paul', 'john'),
('paul', 'paul')) as x(A,B)
[EDIT: Tested Jon's code, his answer on equality sorts of semi-work(just treat the null as false anyway), but his answer on inequality bombs out] [编辑:测试了Jon的代码,他对平等各种半工作的回答(无论如何只是将null视为假),但他对不平等的回答是炸弹的]
Tested the code (Postgres nice boolean support, FTW!): 测试了代码(Postgres很好的布尔支持,FTW!):
select
A, B,
A = B,
A IS NOT DISTINCT FROM B, -- "logically" same as above
coalesce( (A = B) or (A is null and B is null), false ),
-- tested Jon's code for ==, semi-work, coalesced to make it true/false only
A <> B,
A IS DISTINCT FROM B, -- "logically" same as above
(A <> B) and (A is not null or B is not null)
-- tested Jon's code for !=, bombs out
from(
values
(null, null),
(null, 'john'),
(null, 'paul'),
('john', null),
('john', 'john'),
('john', 'paul'),
('paul', null),
('paul', 'john'),
('paul', 'paul')) as x(A,B)
[EDIT: posted another question related to this one] [编辑:发布了与此相关的另一个问题 ]
[EDIT: posted results based on Jon's inquiry on non-working semantics for inequality comparison] [编辑:根据Jon对不平等比较的非工作语义的调查发布结果]
select
A, B,
A = B,
A IS NOT DISTINCT FROM B, -- "logically" same as above
(A = B) or (A is null and B is null),
-- tested Jon's code for ==
A <> B,
A IS DISTINCT FROM B -- "logically" same as above,
(A <> B) and (A is not null or B is not null)
-- tested Jon's code for !=, bombs out
from(
values
(null, null),
(null, 'john'),
(null, 'paul'),
('john', null),
('john', 'john'),
('john', 'paul'),
('paul', null),
('paul', 'john'),
('paul', 'paul')) as x(A,B)
a | b | ?column? | ?column? | ?column? | ?column? | ?column? | ?column?
------+------+----------+----------+----------+----------+----------+----------
null | null | null | t | t | null | f | f
null | john | null | f | null | null | t | null
null | paul | null | f | null | null | t | null
john | null | null | f | null | null | t | null
john | john | t | t | t | f | f | f
john | paul | f | f | f | t | t | t
paul | null | null | f | null | null | t | null
paul | john | f | f | f | t | t | t
paul | paul | t | t | t | f | f | f
(9 rows)
the non-working semantics for inequality prompted me to post another question :-) 不平等的非工作语义促使我发布另一个问题 :-)
[EDIT: Tested Jon's new answer] [编辑:测试乔恩的新答案]
select
A, B,
A = B as e,
A IS NOT DISTINCT FROM B AS e_works, -- "logically" same as above
(A = B) or (A is null and B is null) AS e_semi_work, -- tested Jon's code for ==, works if we treat null as false
A <> B as ie,
A IS DISTINCT FROM B as ie_works, -- "logically" same as above,
(A <> B) and (A is not null or B is not null) as ie_not_work, -- tested Jon's code for !=, bombs out
(A <> B) or ((A is null or B is null) and (A is not null or B is not null)) as ie_semi_works, -- this works(well it is, if you treat null as false),
not ((A = B) or (A is null and B is null)) as ie_not_work2 -- this doesn't work
from(
values
(null, null),
(null, 'john'),
(null, 'paul'),
('john', null),
('john', 'john'),
('john', 'paul'),
('paul', null),
('paul', 'john'),
('paul', 'paul')) as x(A,B)
Results: 结果:
a | b | e | e_works | e_semi_work | ie | ie_works | ie_not_work | ie_semi_works | ie_not_work2
------+------+------+---------+-------------+------+----------+-------------+---------------+--------------
null | null | null | t | t | null | f | f | null | f
null | john | null | f | null | null | t | null | t | null
null | paul | null | f | null | null | t | null | t | null
john | null | null | f | null | null | t | null | t | null
john | john | t | t | t | f | f | f | f | f
john | paul | f | f | f | t | t | t | t | t
paul | null | null | f | null | null | t | null | t | null
paul | john | f | f | f | t | t | t | t | t
paul | paul | t | t | t | f | f | f | f | f
(9 rows)
Edit again ... coalescing the result should work and makes things a bit simpler: 再次编辑...合并结果应该有效并使事情变得更简单:
Equality: 平等:
where COALESCE((A = B) or (A is null and B is null), false)
I agree it's not terribly pleasant. 我同意这不是非常愉快。
EDIT: Vilx pointed out a problem with A <> B
. 编辑:Vilx指出A <> B
的问题。 I think this will work though: 我认为这会有效:
where (A <> B) or ((A is null or B is null) and
(A is not null or B is not null))
It may be simpler to do this though: 这样做可能更简单:
where !(COALESCE((A = B) or (A is null and B is null)), false)
If it's Microsoft SQL Server, then you're looking for the ANSI_NULLS option. 如果是Microsoft SQL Server,那么您正在寻找ANSI_NULLS选项。 If it's another DBMS, you'll have to read the documentation for it. 如果它是另一个DBMS,您将必须阅读它的文档。 Some of them don't support this at all. 他们中的一些根本不支持这一点。
Added: Oh, I noticed you mentioning T-SQL. 补充:哦,我注意到你提到了T-SQL。 It is MSSQL then! 那是 MSSQL! :) :)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.