将GROUP BY汇总为原因和情况-Postgres

时间:2018-08-31 00:28:34

标签: sql database postgresql

我设法找到了一个非常手动的解决方法,但是我敢肯定我希望实现的方法要简单得多。从本质上讲,我试图找出达到“点”(销售额与乘数)并达到阈值(2000)的客户有多少重新折衷 表格示例:

ID      SALES    Multiplier    
10R46   1140.0   Two
10R46   1123.5   Two
100R91  1115.3   One
10R91   2.0      One
10M95   800.0    One
10M95   600.0    Two
10M95   33.0     Zero

我正在使用的当前代码是:

SELECT ID,
        SUM(CASE WHEN Multiplier = 'Two' THEN (trunc(sales * 2)) 
        WHEN Multiplier = 'One' THEN (trunc(sales * 1))
        ELSE 0 END) as points
FROM transactions
GROUP BY ID
HAVING SUM(CASE WHEN Multiplier = 'Two' THEN (trunc(sales * 2)) 
        WHEN Multiplier = 'One' THEN (trunc(sales * 1))
        ELSE 0 END) > 2000

我将从中将结果放入临时表中,并在顶部运行一个trunc sum

SELECT SUM(trunc(points/2000))
FROM temp_table

给出多少次赎回的理想结果(在这种情况下为3)

所以我的主意是,如何简化此过程,并在没有临时表的情况下进行一个查询?

2 个答案:

答案 0 :(得分:2)

使用子查询的一种方式。

select sum(trunc(points/2000))
from (
SELECT ID,
        SUM(CASE WHEN Multiplier = 'Two' THEN (trunc(sales * 2)) 
        WHEN Multiplier = 'One' THEN (trunc(sales * 1))
        ELSE 0 END) as points
FROM transactions
GROUP BY ID
HAVING SUM(CASE WHEN Multiplier = 'Two' THEN (trunc(sales * 2)) 
        WHEN Multiplier = 'One' THEN (trunc(sales * 1))
        ELSE 0 END) > 2000
) t

具有sum窗口功能的另一个选项。

SELECT DISTINCT
        SUM(SUM(CASE WHEN Multiplier = 'Two' THEN (trunc(sales * 2)) 
                     WHEN Multiplier = 'One' THEN (trunc(sales * 1))
                ELSE 0 END
               )/2000
           ) OVER()
FROM transactions
GROUP BY ID
HAVING SUM(CASE WHEN Multiplier = 'Two' THEN (trunc(sales * 2)) 
        WHEN Multiplier = 'One' THEN (trunc(sales * 1))
        ELSE 0 END) > 2000

答案 1 :(得分:0)

如果您想要更简单的查询:

SELECT SUM(trunc(points/2000))
FROM (SELECT t.ID, SUM(TRUNC(sales * mult)) as points
      FROM transactions t JOIN
           (VALUES ('One', 1), ('Two', 2)) v(Multiplier, mult)
           ON t.Multiplier = v.Multiplier
      GROUP BY ID
      HAVING points > 2000
     ) t;

我什至认为您可以消除子查询:

SELECT SUM(SUM(TRUNC(sales * mult) / 2000) OVER ()
FROM transactions t JOIN
     (VALUES ('One', 1), ('Two', 2)) v(Multiplier, mult)
     ON t.Multiplier = v.Multiplier
GROUP BY ID
HAVING points > 2000
FETCH FIRST 1 ROW ONLY;