示例数据:
id | docn | item | suma
---------------------
1 33 x | 10
1 33 y | 20
2 37 a | 10
2 37 b | 20
2 37 c | 30
要对结果进行分组,我可以写:
SELECT sum( suma ),
(ocd.o).*
FROM order_cost_details() ocd
where (ocd.o).id IN ( 6154, 10805 )
GROUP BY ocd.o
但是在一个有群组的地方,我想为每个群组选择last_value
。下一步不起作用:
SELECT sum( suma ),
(ocd.o).*,
last_value( ocd.c ) OVER (PARTITION BY ocd.o )
FROM order_cost_details() ocd
where (ocd.o).id IN ( 6154, 10805 )
GROUP BY ocd.o
SQL Error [42803]: ERROR: column "ocd.c" must appear in the GROUP BY clause or be used in an aggregate function
我将查询重写如下:
SELECT DISTINCT sum( suma ) OVER ( PARTITION BY ocd.o ),
(ocd.o).*,
last_value( ocd.c ) OVER (PARTITION BY ocd.o )
FROM order_cost_details() ocd
where (ocd.o).id IN ( 6154, 10805 )
但是我不确定在这里使用DISTINCT
代替GROUP BY
是否正确?
答案 0 :(得分:2)
last_value()
通常无法按预期运行Window Functions: last_value(ORDER BY ... ASC) same as last_value(ORDER BY ... DESC)
要获取分区的最后一个值,一种更有效的方法是获取降序的第一个值:
SELECT
first_value(my_column) OVER (PARTITION BY partitioned_column ORDER BY order_column DESC)
FROM
...
答案 1 :(得分:0)
您可以使用子选择:
SELECT sum(suma),
(o).*,
last_c
FROM (SELECT suma,
ocd.o
last_value(ocd.c)
OVER (PARTITION BY ocd.o
ORDER BY some_col)
AS last_c
FROM order_cost_details() ocd
where (ocd.o).id IN (6154, 10805)
) AS q
GROUP BY o, last_c;
答案 2 :(得分:0)
来自IRC
RhodiumToad :在上使用 DISTINCT 几乎总是错误(请记住,这完全是标准)
基本经验法则是,当您要减少输出行数时,请使用GROUP BY;而在要保持行数相同时,请使用窗口函数
在分组依据之后,使用窗口功能 不会阻止您对订单进行总计
因此,我将查询重写为:
SELECT *,
sum( t.group_suma ) OVER( PARTITION BY (t.o).id ) AS total_suma
FROM (
SELECT
sum( ocd.item_cost ) AS group_cost,
sum( ocd.item_suma ) AS group_suma,
max( (ocd.ic).consumed ) AS consumed,
ocd.o
FROM order_cost_details() ocd
where (ocd.o).id IN ( 6154, 10805 )
GROUP BY ocd.o, (ocd.ic).consumed_period
) t