SQLite中如何在WHERE子句引用SELECT修改后的字段值?
嘿,我懂你的困扰!在SQLite里,WHERE子句的执行顺序是在SELECT字段计算之前的,所以你没法直接在WHERE里引用SELECT里刚定义的别名(就是你用CASE修改后的cat)。不过不需要新增临时字段也能解决,给你两种实用的方法:
方法1:用派生表(子查询)
把你原来的查询包装成一个子查询,先计算好修改后的cat值,同时保留原始的owner字段避免被覆盖,然后在外层的WHERE里直接引用这些处理后的字段:
SELECT * FROM ( SELECT object.*, list.catlist, -- 计算修改后的cat,起明确别名 CASE WHEN persoon=2 THEN catlist ELSE object.cat END AS modified_cat, -- 保留原始owner用于WHERE判断 object.owner AS original_owner, -- 同时计算修改后的owner(用于最终结果展示) CASE WHEN persoon=2 THEN 'ikke' ELSE object.owner END AS modified_owner, list.persoon FROM object LEFT JOIN list ON (object.id = list.imgref AND list.persoon=2) ) AS subquery -- 这里直接用原始owner和修改后的cat做过滤 WHERE (original_owner = 0 OR persoon = 2) AND ("," || modified_cat || ",") LIKE "%,aap,%"
方法2:用CTE(公共表表达式)
如果你的SQLite版本在3.8.3及以上(现在大部分环境都满足),可以用WITH子句创建临时结果集,写法更直观清晰:
WITH modified_data AS ( SELECT object.*, list.catlist, CASE WHEN persoon=2 THEN catlist ELSE object.cat END AS modified_cat, object.owner AS original_owner, CASE WHEN persoon=2 THEN 'ikke' ELSE object.owner END AS modified_owner, list.persoon FROM object LEFT JOIN list ON (object.id = list.imgref AND list.persoon=2) ) SELECT * FROM modified_data WHERE (original_owner = 0 OR persoon = 2) AND ("," || modified_cat || ",") LIKE "%,aap,%"
为什么原来的写法不行?
SQL的执行逻辑是固定的:先处理FROM和JOIN获取原始数据集,接着执行WHERE过滤行,最后才会执行SELECT里的字段计算和别名赋值。所以在WHERE阶段,你在SELECT里定义的cat别名还没生成,自然没法直接引用。而子查询/CTE是先把所有需要计算的字段处理完成,生成一个临时数据集,外层查询就可以直接调用这些已经计算好的值了。
要是你想在最终结果里还是用cat和owner作为字段名,只需要在外层SELECT的时候把别名改回去就行,完全不用新增多余的临时字段~
内容的提问来源于stack exchange,提问作者Eke
相关产品推荐
相关产品推荐

