SQL中用作谓词的元组是否只是逻辑AND展开的语法糖?
SQL行值表达式(元组谓词)的特性说明
首先可以明确:行值表达式(你所说的谓词元组)不只是逻辑AND的语法糖,除了基础等值场景的等价效果外,还存在很多普通AND/OR写法无法实现或者需要复杂逻辑才能实现的额外特性。
基础场景的等价性
在简单等值匹配场景下,行值表达式的判断逻辑确实和多条件AND完全等价,NULL处理规则也和普通等值判断完全一致,不会自动转换为IS NOT DISTINCT FROM逻辑,你在DB2中的测试结果符合SQL标准规范,所有主流数据库的处理逻辑均相同:
with tmp1(c1,c2,c3) as ( select * from ( values(1,'a','apple') ,(2,'b','ball') ,(3,'c','cat') ,(4,'d','dog') ,(5,'e',null) ) ) -- 以下两条语句执行效果完全等价 select * from tmp1 where (c1,c2,c3) = (1,'a','apple'); select * from tmp1 where c1 = 1 and c2 = 'a' and c3 = 'apple'; -- NULL判断规则和普通等值一致,任意字段为NULL时整体判断结果为NULL,无匹配行 select * from tmp1 where (c1,c2,c3) = (5,'e',null); -- 返回空结果集
额外独有特性
多列范围/排序逻辑判断大幅简化
要实现基于多列的顺序比较,普通写法需要嵌套AND/OR逻辑,而行值表达式可以直接简化书写,比如(c1,c2) > (3, 'c')对应的普通写法为c1 > 3 OR (c1 = 3 AND c2 > 'c'),列数越多简化效果越明显,这类写法在多列排序的游标分页场景下非常实用。多值批量匹配更简洁不易出错
当需要匹配多组多列组合条件时,行值表达式可以大幅减少冗余代码,比如:-- 行值写法 SELECT * FROM tmp1 WHERE (c1,c2) IN ((1,'a'),(2,'b'),(3,'c')); -- 等价普通写法 SELECT * FROM tmp1 WHERE (c1=1 AND c2='a') OR (c1=2 AND c2='b') OR (c1=3 AND c2='c');匹配的组合数越多,行值写法的可读性和可维护性优势越明显。
多列关联条件更清晰
多表JOIN需要匹配多个字段时,行值写法可以让关联条件更直观,减少漏写关联条件的概率:-- 行值写法 SELECT * FROM tmp1 t1 JOIN tmp2 t2 ON (t1.c1,t1.c2,t1.c3) = (t2.c1,t2.c2,t2.c3); -- 等价普通写法 SELECT * FROM tmp1 t1 JOIN tmp2 t2 ON t1.c1 = t2.c1 AND t1.c2 = t2.c2 AND t1.c3 = t2.c3;
注:不同数据库对行值表达式的支持程度存在差异,比如SQL Server 2022之前的版本仅支持行值的等值匹配和IN子句,不支持范围比较操作,使用前可确认对应数据库的版本兼容情况。
内容的提问来源于stack exchange,提问作者Dhrubajyoti Gogoi
相关产品推荐
相关产品推荐

