
# 如何优化包含多个CASE WHEN条件的SQL查询？
在业务查询中，CASE WHEN语句常用来进行条件判断，但如果在SQL查询中存在大量冗余的CASE WHEN，例如：
```
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计算部分提取出来，放到一个临时的结果集中或者子查询中。这样可以减少在主查询中的重复计算逻辑。
例如，先创建一个子查询来计算中间结果：
```
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。
```
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进行查询。
```
SELECT
  count_a_gt_value(1) AS a1,
  count_a_gt_value(2) AS a2
FROM test;
```
