SQL中CASE-IN子句替换为子查询报错,求替代实现方案
解决方案
你遇到的报错是因为SQL Server不允许在聚合函数(如SUM)的表达式中直接嵌套子查询。以下是几种可行的改写方式:
方式1:用CTE预存不良属性集合
先从other_table提取所有不良属性,再通过左连接验证所有属性都属于不良集合:
WITH bad_attributes AS ( SELECT DISTINCT id_attribute FROM other_table WHERE description = 'bad' ) SELECT x, y FROM (SELECT DISTINCT x, y, id_attribute FROM [table]) t LEFT JOIN bad_attributes ba ON t.id_attribute = ba.id_attribute GROUP BY x, y HAVING COUNT(ba.id_attribute) = COUNT(t.id_attribute);
逻辑说明:左连接后,若某属性不属于不良集合,ba.id_attribute会为NULL。当匹配到不良属性的数量等于该x,y组合的总属性数时,说明所有属性都是不良的。
方式2:用NOT EXISTS排除含非不良属性的记录
换个思路,直接筛选那些不存在任何非不良属性的x,y组合:
SELECT DISTINCT x, y FROM [table] t_main WHERE NOT EXISTS ( SELECT 1 FROM [table] t_sub WHERE t_sub.x = t_main.x AND t_sub.y = t_main.y AND t_sub.id_attribute NOT IN ( SELECT DISTINCT id_attribute FROM other_table WHERE description = 'bad' ) );
这种写法逻辑更直观,且SQL Server通常能对这类关联查询做较好的优化。
方式3:用临时表存储不良属性(适合频繁查询场景)
如果不良属性不常变化,可以把查询结果存入临时表,再用于主查询:
SELECT DISTINCT id_attribute INTO #bad_attributes FROM other_table WHERE description = 'bad'; SELECT x, y FROM (SELECT DISTINCT x, y, id_attribute FROM [table]) t GROUP BY x, y HAVING SUM(CASE WHEN id_attribute IN (SELECT id_attribute FROM #bad_attributes) THEN 0 ELSE 1 END) = 0; DROP TABLE #bad_attributes;
内容的提问来源于stack exchange,提问作者Ma0
相关产品推荐
相关产品推荐

