如何优化包含多个CASE WHEN条件的SQL查询?
在业务查询中,CASE WHEN语句常用来进行条件判断,但如果在SQL查询中存在大量冗余的CASE WHEN,例如:
1 2 3 4 5 6 |
SELECT SUM(CASE WHEN a > 1 THEN 1 ELSE 0 END) AS a1, SUM(CASE WHEN a > 2 THEN 1 ELSE 0 END) AS a2, ... FROM test WHERE dt = '20241225'; |
该语句冗长,执行时每个分支的CASE WHEN均需执行,导致查询时间成倍增加,影响查询性能。
DWS提供以下优化策略来解决此类问题。
使用临时结果集或者子查询
将复杂的CASE WHEN计算部分提取出来,放到一个临时的结果集中或者子查询中。这样可以减少在主查询中的重复计算逻辑。
例如,先创建一个子查询来计算中间结果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
SELECT sub.a1, sub.a2 FROM ( SELECT sum(case when a > 1 then 1 else 0 end) AS a1, sum(case when a > 2 then 1 else 0 end) AS a2 FROM test WHERE dt = '20241225' ) sub; SELECT SUM(case_when_a1) as a1, SUM(case_when_a2) as a2, ... FROM ( SELECT CASE WHEN a > 1 THEN 1 ELSE 0 END AS case_when_a1, CASE WHEN a > 2 THEN 1 ELSE 0 END AS case_when_a2, ... FROM test WHERE dt = '20241225' ) AS subquery; |
使用自定义函数
将CASE WHEN的逻辑封装成一个函数。这样在查询中只需要调用该函数,而不是多次编写相同的CASE WHEN逻辑。
例如,创建一个简单的函数count_a_gt_value。
1 2 3 4 5 6 7 8 9 10 11 12 |
CREATE OR REPLACE FUNCTION count_a_gt_value(val INT) RETURNS INT AS $$ DECLARE result INT; BEGIN SELECT sum(CASE WHEN a > val THEN 1 ELSE 0 END) INTO result FROM test WHERE dt = '20241225'; RETURN result; END; $$ LANGUAGE plpgsql; |
再使用自定义函数count_a_gt_value进行查询。
1 2 3 4 |
SELECT count_a_gt_value(1) AS a1, count_a_gt_value(2) AS a2 FROM test; |