正如标题所示,我想选择用GROUP BY分组的每组行中的第一行。
具体来说,如果我有一个如下所示的采购表:
SELECT * FROM purchases;
我的输出:
id |
customer |
total |
1 |
Joe |
5 |
2 |
Sally |
3 |
3 |
Joe |
2 |
4 |
Sally |
1 |
我想查询每个客户的最大购买量(总购买量)。类似于:
SELECT FIRST(id), customer, FIRST(total)
FROM purchases
GROUP BY customer
ORDER BY total DESC;
预期输出:
FIRST(id) |
customer |
FIRST(total) |
1 |
Joe |
5 |
2 |
Sally |
3 |
我通过窗口函数dbfiddle的方法:
将每组的row_number()分配给(按agreement_id、order_id划分)为nrow只取组:filter中的第一行(其中nrow=1)
with intermediate as (select
*,
row_number() over ( partition by agreement_id, order_id ) as nrow,
(sum( suma ) over ( partition by agreement_id, order_id ))::numeric( 10, 2) as order_suma,
from <your table>)
select
*,
sum( order_suma ) filter (where nrow = 1) over (partition by agreement_id)
from intermediate
在Postgres中,您可以这样使用array_agg:
SELECT customer,
(array_agg(id ORDER BY total DESC))[1],
max(total)
FROM purchases
GROUP BY customer
这将为您提供每个客户最大购买量的id。
需要注意的一些事项:
array_agg是一个聚合函数,因此它与GROUP BY一起工作。arrayagg允许您指定仅限于自身的排序,因此它不会约束整个查询的结构。如果您需要执行与默认值不同的操作,还可以使用语法对NULL进行排序。一旦我们构建了数组,我们就使用第一个元素。(Postgres数组是1索引的,而不是0索引的)。您可以以类似的方式对第三个输出列使用array_agg,但max(total)更简单。与DISTINCT ON不同,使用array_agg可以保留GROUP BY,以防出于其他原因需要。
如果要从聚合行集合中选择任何行(根据特定条件)。如果您想使用除max/min之外的另一个(sum/avg)聚合函数。因此,您不能在DISTINCT ON时使用线索
您可以使用下一个子查询:
SELECT
(
SELECT **id** FROM t2
WHERE id = ANY ( ARRAY_AGG( tf.id ) ) AND amount = MAX( tf.amount )
) id,
name,
MAX(amount) ma,
SUM( ratio )
FROM t2 tf
GROUP BY name
您可以将amount=MAX(tf.amount)替换为任何需要的条件,但有一个限制:此子查询不能返回多行
但是如果你想做这样的事情,你可能需要寻找窗口函数