如何在case语句中使用分区

时间:2016-04-21 11:24:18

标签: sql postgresql greatest-n-per-group postgresql-9.1 window-functions

以下是select语句的结果

   u_id | l_id | risk      | Count | Avg
----------------------------------------
|   1   |  10  |Critical   |  3    | 33.33
|   1   |  10  |Limited    |  3    | 33.33
|   1   |  10  |Medium     |  2    | 22.22
|   1   |  10  |Significant|  1    | 11.11
|   2   |  9   |Medium     |  1    | 50.00
|   2   |  9   |Significant|  1    | 50.00
|   3   |  8   |Limited    |  1    | 50.00
|   3   |  8   |Medium     |  1    | 50.00

我使用case语句从select语句中获取结果,但我希望得到的结果使u_id和l_id成为唯一。

案例陈述:

SELECT u_id, l_id, (CASE WHEN risk = 'Critical' THEN 'Critical'
         WHEN risk = 'Significant' AND avg >= 50 THEN 'Critical'
         WHEN risk = 'Significant' AND risk <> 'Critical' THEN 'Significant'
         WHEN risk = 'Medium' AND avg >= 50 THEN 'Medium'
         ELSE 'Limited' -- OVER (PARTITION BY u_id,l_id) 
         END) as crr 
         From
             ( select ...(select ... ) a .. ) b 

实际结果

  u_id | l_id | risk      
--------------------------
|   1   |  10  |Critical   
|   1   |  10  |Limited    
|   1   |  10  |Limited    
|   1   |  10  |Significant
|   2   |  9   |Medium     
|   2   |  9   |Critical   
|   3   |  8   |Limited    
|   3   |  8   |Medium     

我期待的是

   u_id | l_id | risk      
--------------------------
|   1   |  10  |Critical   
|   2   |  9   |Critical  
|   3   |  8   |Medium

感谢。

1 个答案:

答案 0 :(得分:1)

Postgres有一个很好的语法:distinct on

SELECT DISTINCT ON (u_id, l_id) u_id, l_id,
       (CASE WHEN risk = 'Critical' THEN 'Critical'
             WHEN risk = 'Significant' AND avg >= 50 THEN 'Critical'
             WHEN risk = 'Significant' AND risk <> 'Critical' THEN 'Significant'
             WHEN risk = 'Medium' AND avg >= 50 THEN 'Medium'
             ELSE 'Limited' -- OVER (PARTITION BY u_id,l_id) 
        END) as crr 
FROM ( select ...(select ... ) a .. ) b 
ORDER BY u_id, l_id, ??;

这里的关键是ORDER BY。我猜你想要最高的风险。一种方法是:

ORDER BY u_id, l_id,
          (case when risk = 'Critical' then 1
           . . .
          )