[英]Simplest SQL expression to check if two columns have same value accounting for NULL [duplicate]
这个问题已经在这里有了答案:
我试图找出最简单的通用 SQL表达式,该表达式可以检查a
和b
两列是否相同。 换句话说,在以下情况下计算结果为true
的表达式:
a
为NULL
, b
为NULL
; 要么 a
不是NULL
且b
不是NULL
且a = b
假设列a
和b
具有完全相同的数据类型。
我在下面的示例中使用的最明显的解决方案令人费解,尤其是因为我需要在15列的表中重复此子句15x:
SELECT * FROM (
SELECT 'x' a, 'x' b FROM dual
UNION ALL
SELECT 'x' a, NULL b FROM dual
UNION ALL
SELECT NULL a, 'x' b FROM dual
UNION ALL
SELECT NULL a, NULL b FROM dual
UNION ALL
SELECT 'x' a, 'y' b FROM dual
UNION ALL
SELECT 'x' a, NULL b FROM dual
UNION ALL
SELECT NULL a, 'y' b FROM dual
UNION ALL
SELECT NULL a, NULL b FROM dual
)
WHERE (a IS NULL AND b IS NULL) OR
(a IS NOT NULL AND b IS NOT NULL AND a = b)
/
预期结果是:
+--------+--------+
| a | b |
+--------+--------+
| x | x |
| (null) | (null) |
| (null) | (null) |
+--------+--------+
tl; dr-我可以简化我的WHERE
子句, 即使其更紧凑,同时保持其逻辑上正确吗?
PS:我不能对“ NULL
不是值”的任何SQL纯粹主义者的坚持给予谴责。 出于我的实际目的,如果a
包含NULL
而b
不包含NULL
,则a
与 b
不同 。 它们是否不同并不是“未知的”。 所以,请不要在那条小巷前争吵!
PPS:我的SQL风格是Oracle 11g。
PPPS:有人认为此问题与“ 是否有更好的Oracle运算符进行null安全的相等性检查? ”重复,但是粗略地检查该问题将显示答案没有此线程上发布的答案有用,并且没有满足我特定的明确陈述的标准 。 仅仅因为它们相似就不会使它们重复。 我从未理解过为什么SO的人们如此努力地迫使我的问题X成为别人的问题Y。
您可以轻松地将其简化为:
WHERE (a IS NULL AND b IS NULL) OR
(a = b)
不需要IS NOT NULL
。
如果您具有“安全”值(即从未使用过的值),则可以执行以下操作:
WHERE COALESCE(a, ' ') = COALESCE(b, ' ')
假设' '
不是有效值。
我发现Ask Tom文章“安全比较相等的NULL列”是最有用的。 在Oracle中,可以使用DECODE
函数执行此操作:
WHERE 1 = DECODE(a, b, 1, 0)
这是迄今为止我所见过的最紧凑的解决方案。
简单不一定是高效的。
考虑这种可能性。
WHERE X || 'x' = Y || 'x'
如果您想真正推动发展,请使用SYS_OP_MAP_NONNULL
SELECT * FROM (
SELECT 'x' a, 'x' b FROM dual
UNION ALL
SELECT 'x' a, NULL b FROM dual
UNION ALL
SELECT NULL a, 'x' b FROM dual
UNION ALL
SELECT NULL a, NULL b FROM dual
UNION ALL
SELECT 'x' a, 'y' b FROM dual
UNION ALL
SELECT 'x' a, NULL b FROM dual
UNION ALL
SELECT NULL a, 'y' b FROM dual
UNION ALL
SELECT NULL a, NULL b FROM dual
)
WHERE NVL(a,'1')=NVL(b,'1')
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.