T-SQL XOR运算符

67
在SQL Server(T-SQL)中是否存在XOR运算符或等效函数?

1
我猜我试图在可空的varchar列上使用。例如:WHERE(Note为null)^(ID为null)。我收到“附近的语法不正确”错误提示。 - ses011
https://dev59.com/32025IYBdhLWcg3wblc3 - Mr. TA
1
请注意,Microsoft SQL区分位运算符(如and |、&、^ [链接](https://learn.microsoft.com/en-us/sql/t-sql/language-elements/bitwise-operators-transact-sql))和逻辑布尔运算符(即true和false)在WHERE子句或CASE语句中使用等。 (这很令人惊讶,因为在计算机中(MS声称专业),布尔和逻辑值是相同的,即1 = true,0 = false)。 您似乎正在询问逻辑运算符,因为您的评论提到了“WHERE”。 - Reversed Engineer
2
据我所知,即使是 SQL 2017,也没有逻辑异或运算符,因此您可以使用 (A OR B) AND NOT (A AND B) 或者 (A AND NOT B) OR (B AND NOT A) 来模拟它。好的,现在再慢慢地读一遍哈哈 :) 这一切都不是假的。 - Reversed Engineer
如果SQL Server有布尔类型作为一等公民,你可以通过与“=”进行比较来执行它们的异或操作,但遗憾的是,它没有。 - jpmc26
8个回答

61

有一个按位异或运算符 - 插入符号(^),例如:

SELECT 170 ^ 75
结果为225。 对于逻辑异或,使用ANY关键字和NOT ALL,即:
WHERE 5 > ANY (SELECT foo) AND NOT (5 > ALL (SELECT foo))

3
没错,你读对了。如果满足一个或多个条件,XOR 返回真,但是如果所有条件都不满足或者全部满足,XOR 返回假。我们可以使用“ANY”来检查集合中任意一个或多个值是否满足条件。“NOT … ALL” 部分确保当所有条件都被满足时,表达式返回假。 - Nathan Rivera
1
哦,非常有趣。这是我没有真正涉及过的T-SQL的一部分。 - ses011
9
我不太清楚这个回答如何回答他在问题评论中澄清的例子所提出的问题。 - djs
1
请注意,HarveyFrench提供的链接仅适用于SQL 2014及更高版本。此外,这是相关的,因为它涉及位运算,而楼主似乎在询问(楼主使用了"^"这个位运算符)。然而,为了帮助其他人,我想指出非位运算的异或操作直到SQL 2016才可用。 - Andrew Steitz
真 XOR 真 XOR 假 = 假。但我相信在这个给定的例子中,使用 ANY 逻辑会产生一个“真”的结果。 - Shawn Kovac
显示剩余2条评论

43

使用布尔代数,可以很容易地证明:

A xor B = (not A and B) or (A and not B)


A B | f = notA and B | g = A and notB | f or g | A xor B    
----+----------------+----------------+--------+--------    
0 0 | 0              | 0              | 0      | 0    
0 1 | 1              | 0              | 1      | 1    
1 0 | 0              | 1              | 1      | 1    
1 1 | 0              | 0              | 0      | 0

这真是救了我的一天,谢谢!(TinyTDS在Rails上,真是让人头疼) - JeanLescure
13
如果你的条件很长,这不太合适。 - jpmc26
如果你有5个字段要进行异或操作,祝你好运去组合它们! - Raheel Hasan

23

根据您的评论,Spacemoses提供了一个例子:WHERE(Note为null)^(ID为null)。我不明白为什么您选择接受此处给出的任何答案作为回答。如果我需要XOR操作,我认为我需要使用AND/OR等效逻辑:

WHERE (Note is null and ID is not null) OR (Note is not null and ID is null)

那相当于:

WHERE (Note is null) XOR (ID is null)

当“XOR”不可用时。


19

仅适用于 MS SQL 的简称(自 SQL Server 2012 起):

1=iif( a=b ,1,0)^iif( c=d ,1,0)

1
很可爱。如果这是我店里的常见快捷方式,我会进行评论。我对查询优化器如何处理它与@shawn-kovac更明确的答案很感兴趣。但我不太好奇,不想停下来测试它。 - Karl Kieninger
1
这应该是最佳答案,因为a=b和c=d只被调用一次。在表达式昂贵的情况下,这一点非常重要。问题询问了XOR对逻辑表达式的作用。 - xxyzzy
1
请注意,这与空值的行为不同。如果其中一个值为空,则结果可能与“(a = b and c <> d) or (a <> b and c = d)”不同。 - Ricardo Rocha

5

xor操作符是^

例如:SELECT A ^ B,其中A和B是整数类型的数据。


这不通过语法验证: - simon
这并没有回答原问题。是的,它回答了按照提问方式提出的问题,但是如果你阅读评论,第一个评论问“为什么?”因为有两种非常不同的XOR。一种是按位XOR。另一种是逻辑XOR。问题并没有明确表明他正在询问哪一个。但是评论问他需要哪一个,他真正的需求不是按位XOR,即'^'。因此,这个答案并没有解决所请求的问题。 - Shawn Kovac
问题的评论澄清了他不需要整数的XOR,这是“按位”XOR。真正的问题是逻辑异或,而不是按位XOR,它像WHERE(Note为null)^(ID为null)这样使用。请注意,这些不是整数XOR操作。 - Shawn Kovac
1
@ShawnKovac 感谢澄清,但您应该注意到我在6年前发布了这个答案,比OP澄清之前几分钟,当时还没有更好的答案 - 我也不认为用不同于OP期望的答案回答问题是错误的,只要它对搜索此问题的人有用,因为他们可能正在寻找此解决方案。 - Sebi
@Sebi,啊,我之前没有注意到你已经回答过这个问题并进行了澄清。谢谢你让我明白了这一点。我的错。以后我会更加注意这种情况,并感谢你的分享,让我以后更加敏锐。并且,我同意如果其他人也可能会发现答案有用,那么回答类似问题也是可以的。对于你的回答,我甚至都没有表达感谢,我很抱歉。但我在这里感谢你的回答,Sebi,并特别感谢你从上次评论中教给我的东西!我给你两方面的智慧+1。 - Shawn Kovac
1
@ShawnKovac 可能值得编辑问题,而不是在此答案上进行评论。 - user1007074

2

赶我一步。注意:此功能仅适用于SQL Server 2005+。另请注意:这是位运算符,而不是逻辑运算符。 - Dan J
2000年可用 http://msdn.microsoft.com/zh-cn/library/aa276869(SQL.80).aspx - SQLMenace
这并没有回答原问题。是的,它回答了按照提问方式提出的问题,但是如果你阅读评论,第一个评论问“为什么?”因为有两种非常不同的XOR。一种是按位XOR。另一种是逻辑XOR。问题并没有明确表明他在问哪一个。但是评论问他需要哪一个,他真正的需求不是按位XOR,即'^'。因此,这个答案并没有解决所请求的问题。 - Shawn Kovac

2

<>通常是XOR的很好替代,只要它适用于布尔值。

原始答案:最初的回答

只有使用CASE表达式才会是真的。例如:CASE WHEN A <> B THEN 1 ELSE 0 END - PollusB

1
从您的评论中:

示例:WHERE(Note为空)^(ID为空)

您可以尝试:

where
   (case when Note is null then 1 else 0 end)
 <>(case when ID is null then 1 else 0 end)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接