SQLite:如何在CASE语句中复用COALESCE的计算结果
你碰到的这个报错不是SQLite的bug,是SQL标准的执行逻辑决定的:SELECT子句里定义的列别名,不能在同层级的SELECT、WHERE、GROUP BY里直接引用,因为数据库执行查询时,会先处理FROM、JOIN、筛选、分组逻辑,最后才计算SELECT里的字段和别名,所以你在同个SELECT的CASE里直接用前面定义的value别名,数据库识别不到。
你可以用以下几种方案实现计算结果复用,同时保证可读性:
解决方案
1. 用CTE(公共表表达式,可读性最高,推荐)
先在CTE里把value计算好,外层查询直接引用别名即可:
WITH user_values AS ( SELECT -- 所有需要提前计算的字段都可以放在这层 user_id, COALESCE(latest_of_series, initial_if_no_series) AS value FROM 初始表 JOIN 变更表 ON 你的关联条件 ) SELECT value, CASE WHEN value > 1 AND value < 100 THEN 'group 1' WHEN value >= 100 AND value < 500 THEN 'group 2' -- 其他区间规则 ELSE 'other' END AS `group` FROM user_values -- 后续筛选、排序、分组都可以直接用value别名 ORDER BY `group`, value DESC;
2. 用嵌套子查询
逻辑和CTE完全一致,只是写法上把子查询嵌套在FROM里:
SELECT value, CASE WHEN value > 1 AND value < 100 THEN 'group 1' -- 其他区间规则 END AS `group` FROM ( SELECT COALESCE(latest_of_series, initial_if_no_series) AS value FROM 你的表关联逻辑 ) AS temp_table
3. 用VALUES子句横向提前计算(适合不想嵌套多层的场景)
SQLite支持从VALUES子句中获取预先计算的值,也可以实现别名复用:
SELECT v.value, CASE WHEN v.value > 1 AND v.value < 100 THEN 'group 1' -- 其他区间规则 END AS `group` FROM 初始表 JOIN 变更表 ON 关联条件 JOIN (VALUES (COALESCE(latest_of_series, initial_if_no_series))) AS v(value) ON 1=1
内容的提问来源于stack exchange,提问作者Adam Kiss
相关产品推荐
相关产品推荐

