SQL查询中如何避免SELECT与WHERE子句重复使用目标值?
避免SQL中重复书写目标值的方案
你可以通过CTE(公共表表达式)+ 自定义函数的组合,彻底避免重复书写correct_value这类目标值,同时实现近似你想要的简洁写法,以下是具体实现:
方案1:自定义函数 + CTE(最简洁)
先创建一个通用的检查函数(以MySQL为例,不同数据库语法略有调整):
CREATE FUNCTION check_value(col_value VARCHAR(255), correct_val VARCHAR(255)) RETURNS VARCHAR(500) DETERMINISTIC BEGIN RETURN CASE WHEN col_value = correct_val THEN col_value ELSE CONCAT(col_value, '->', correct_val) END; END;
然后用CTE存储所有字段的目标值,后续只需引用CTE中的变量:
WITH target_values AS ( SELECT 'correct_value1' AS val1_correct, 'correct_value2' AS val2_correct ) SELECT check_value(t.value1, tv.val1_correct) AS value1_check, check_value(t.value2, tv.val2_correct) AS value2_check FROM t CROSS JOIN target_values tv WHERE t.value1 <> tv.val1_correct OR t.value2 <> tv.val2_correct;
这里目标值仅在CTE中定义一次,SELECT和WHERE子句都通过引用CTE变量使用,完全杜绝重复书写。
方案2:仅用CTE简化(无需自定义函数)
如果不想创建自定义函数,直接用CTE配合CASE表达式也能实现:
WITH target_values AS ( SELECT 'correct_value1' AS val1_correct, 'correct_value2' AS val2_correct ) SELECT CASE WHEN t.value1 = tv.val1_correct THEN t.value1 ELSE CONCAT(t.value1, '->', tv.val1_correct) END AS value1_check, CASE WHEN t.value2 = tv.val2_correct THEN t.value2 ELSE CONCAT(t.value2, '->', tv.val2_correct) END AS value2_check FROM t CROSS JOIN target_values tv WHERE t.value1 <> tv.val1_correct OR t.value2 <> tv.val2_correct;
说明
你想要的where any not correct row这种自然语言式写法,SQL本身并不支持,但上述两种方案已经实现了等价逻辑,同时彻底解决了目标值重复书写的问题。另外,不同数据库的函数创建语法略有差异(比如PostgreSQL用CREATE OR REPLACE FUNCTION,SQL Server有专属的函数定义语法),但核心思路一致。
内容的提问来源于stack exchange,提问作者jonjk
相关产品推荐
相关产品推荐

