最简单的SQL表达式,用于检查两个列是否具有相同的值,并考虑NULL
我试图找出最简单的通用SQL表达式,它可以检查最简单的SQL表达式,用于检查两个列是否具有相同的值,并考虑NULL,sql,oracle,oracle11g,null,Sql,Oracle,Oracle11g,Null,我试图找出最简单的通用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,
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
子句吗(使其更紧凑,同时保持逻辑正确?
附言:对于任何SQL纯粹主义者坚持认为“NULL
不是一个值”,我一点也不在乎。出于实际目的,如果a
包含NULL
而b
不包含,则a
与b
不同。它们是否不同并不“未知”。所以,请事先不要在那条巷子里争吵
附言:我的SQL风格是Oracle 11g
p.p.p.S.:有人认为这个问题是“”的重复,但粗略检查一下这个问题,就会发现答案没有贴在这个帖子上的答案有用,并且不符合我特别明确的标准。仅仅因为它们相似,并不意味着它们是重复的。我一直不明白为什么人们如此努力地把我的问题X变成其他人的问题Y。简单不一定是有效的 考虑一下这种可能性
WHERE X || 'x' = Y || 'x'
如果您真的想推动信封,请使用非空的SYS\u OP\u MAP\u您可以将其简化为:
WHERE (a IS NULL AND b IS NULL) OR
(a = b)
不为空
不需要
如果您有一个“安全”值(即从未使用过的值),您可以执行以下操作:
WHERE COALESCE(a, ' ') = COALESCE(b, ' ')
这假设
'
不是有效值。我发现Ask Tom文章最有帮助。在Oracle中,您可以使用该函数执行以下操作:
WHERE 1 = DECODE(a, b, 1, 0)
这是迄今为止我见过的最紧凑的解决方案。我不关心性能。我只关心表达的紧凑性。有趣。什么样的业务条件使它成为一个问题?代码的紧凑性和可读性?一种普遍倾向于简单、简洁而不是冗长、难以阅读。我想你可以有把握地假设,因为我说过紧凑性是我的目标,我对我正在处理的数据有足够的了解,所以知道
WHERE
子句的性能并不是什么大问题。我通常在SQL Server中使用ISNULL()
函数,我认为NVL()
在Oracle中是等效的,也许试着看看这个函数?NVL()不起作用。LNNVL应该有用。LNNVL
这个重复的问题正是你想要的。你是对的。我瞎了(.谢谢@Noel.我没有意识到LNNVL
优于DECODE
,但事实确实如此。我刚刚对我自己的问题投了赞成票:)第一个肯定更好。我没有意识到这是真的。然而,我没有一个安全值可用于COALESCE
。我想要一个不需要假设给定值不会出现在数据集中的解决方案。请参阅下面我对@Gordon Linoff回答的评论:“但是,我没有一个安全值可用于COALESCE”。您可以将“1”替换为数据集中永远不会出现的内容(可以是“xxxxx”或“AAAA”或其他任何内容)
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')