PostgreSQL中IN运算符结合CASE WHEN的使用问题求助
问题原因
你当前的写法存在核心逻辑错误:CASE WHEN生成的Rangecriteria是单个字符串值(比如周一返回的是'Range1','Range2','Range3'这个完整字符串),而IN运算符需要的是多个独立的筛选值,并非把整个字符串当作一个匹配项。因此column2 IN (Rangecriteria)实际是判断column2是否等于这个带引号和逗号的完整字符串,自然无法得到预期结果。
解决方案
方案一:直接将CASE逻辑嵌入WHERE子句(推荐)
这是最简洁高效的方式,完全规避字符串解析问题:
SELECT column1, column2 FROM sampletable WHERE CASE TRIM(TO_CHAR(current_date, 'Day')) WHEN 'Monday' THEN column2 IN ('Range1', 'Range2', 'Range3') WHEN 'Tuesday' THEN column2 IN ('Range4', 'Range5', 'Range6') WHEN 'Wednesday' THEN column2 IN ('Range7', 'Range8', 'Range9') WHEN 'Thursday' THEN column2 IN ('Range10', 'Range11') WHEN 'Friday' THEN column2 IN ('Range12', 'Range13') ELSE TRUE -- 非工作日可根据需求改为FALSE,控制是否返回数据 END;
方案二:CTE+字符串拆分(适合需复用筛选条件的场景)
不同数据库的字符串拆分函数不同,以下是常见数据库的实现:
PostgreSQL
使用STRING_TO_ARRAY将字符串转为数组,配合ANY运算符匹配:
WITH sampleq AS ( SELECT CASE TRIM(TO_CHAR(current_date, 'Day')) WHEN 'Monday' THEN 'Range1,Range2,Range3' WHEN 'Tuesday' THEN 'Range4,Range5,Range6' WHEN 'Wednesday' THEN 'Range7,Range8,Range9' WHEN 'Thursday' THEN 'Range10,Range11' WHEN 'Friday' THEN 'Range12,Range13' ELSE '' END AS Rangecriteria, column1, column2 FROM sampletable ) SELECT * FROM sampleq WHERE column2 = ANY(STRING_TO_ARRAY(Rangecriteria, ','));
Oracle
使用APEX_STRING.SPLIT拆分字符串(需Oracle 12c及以上,或自定义拆分函数):
WITH sampleq AS ( SELECT CASE TRIM(TO_CHAR(current_date, 'Day')) WHEN 'Monday' THEN 'Range1,Range2,Range3' WHEN 'Tuesday' THEN 'Range4,Range5,Range6' WHEN 'Wednesday' THEN 'Range7,Range8,Range9' WHEN 'Thursday' THEN 'Range10,Range11' WHEN 'Friday' THEN 'Range12,Range13' ELSE '' END AS Rangecriteria, column1, column2 FROM sampletable ) SELECT sq.* FROM sampleq sq WHERE EXISTS ( SELECT 1 FROM TABLE(APEX_STRING.SPLIT(sq.Rangecriteria, ',')) s WHERE s.COLUMN_VALUE = sq.column2 );
方案三:数组赋值(PostgreSQL专属)
直接通过CASE返回数组类型,配合ANY匹配:
WITH sampleq AS ( SELECT CASE TRIM(TO_CHAR(current_date, 'Day')) WHEN 'Monday' THEN ARRAY['Range1', 'Range2', 'Range3'] WHEN 'Tuesday' THEN ARRAY['Range4', 'Range5', 'Range6'] WHEN 'Wednesday' THEN ARRAY['Range7', 'Range8', 'Range9'] WHEN 'Thursday' THEN ARRAY['Range10', 'Range11'] WHEN 'Friday' THEN ARRAY['Range12', 'Range13'] ELSE ARRAY[]::TEXT[] END AS Rangecriteria, column1, column2 FROM sampletable ) SELECT * FROM sampleq WHERE column2 = ANY(Rangecriteria);
内容的提问来源于stack exchange,提问作者Avinash
相关产品推荐
相关产品推荐

