如何获取聚合函数选择的行的id? [复制]
Posted
技术标签:
【中文标题】如何获取聚合函数选择的行的id? [复制]【英文标题】:How to get id of the row which was selected by aggregate function? [duplicate] 【发布时间】:2019-03-04 04:57:36 【问题描述】:我有下一个数据:
id | name | amount | datefrom
---------------------------
3 | a | 8 | 2018-01-01
4 | a | 3 | 2018-01-15 10:00
5 | b | 1 | 2018-02-20
我可以将结果与下一个查询分组:
select name, max(amount) from table group by name
但我也需要所选行的id
。因此我尝试了:
select max(id), name, max(amount) from table group by name
正如预期的那样,它会返回:
id | name | amount
-----------
4 | a | 8
5 | b | 1
但我需要3
的id 才能达到8
的数量:
id | name | amount
-----------
3 | a | 8
5 | b | 1
这可能吗?
PS。这是计费任务所必需的。在某一天,a
的 2018-01-15
配置发生了更改,用户在 10 小时内消耗了一些资源,数量为 8
,并在 14 小时内休息——3
。我需要用最大值来计算这样的一天。因此,id = 4
的行在 2018 年 1 月 15 日被忽略。 (第二天2018-01-16我会开票3
)
所以我采取对行计费:
3 | a | 8 | 2018-01-01
如果它有问题。我必须报告id == 3
的那一行是错误的。
但是当我使用聚合函数时,id
的信息丢失了。
如果可以的话,那就太棒了:
select current(id), name, max(amount) from table group by name
select aggregated_row(id), name, max(amount) from table group by name
这里agg_row
指的是被聚合函数max
选中的行
UPD 我将任务解决为:
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
UPD 使用window functions会好很多
【问题讨论】:
关于您的更新:运算符为int = ANY(int[])
,但DISTINCT ON
则不需要子查询。
@S-Man:请你写一下使用 SQL 的样子?
操作员在这个小提琴中演示:dbfiddle.uk/… 但如果不完全重建它,我真的无法让您的“更新”查询工作 - 有太多问题......这也是复杂:D
@S-Man:谢谢。现在我修复我的查询。 Here是吗
【参考方案1】:
至少有3种方式,见下:
CREATE TEMP TABLE test (
id integer, name text, amount numeric, datefrom timestamptz
);
COPY test FROM STDIN (FORMAT csv);
3,a,8,2018-01-01
4,a,3,2018-01-15 10:00
5,b,1,2018-02-20
6,b,1,2019-01-01
\.
方法 1. 使用 DISTINCT ON (PostgreSQL-specific)
SELECT DISTINCT ON (name)
id, name, amount
FROM test
ORDER BY name, amount DESC, datefrom ASC;
方法2.使用窗口函数
SELECT id, name, amount FROM (
SELECT *, row_number() OVER (
PARTITION BY name
ORDER BY amount DESC, datefrom ASC) AS __rn
FROM test) AS x
WHERE x.__rn = 1;
方法3.使用关联子查询
SELECT id, name, amount FROM test
WHERE id = (
SELECT id FROM test AS t2
WHERE t2.name = test.name
ORDER BY amount DESC, datefrom ASC
LIMIT 1
);
【讨论】:
【参考方案2】:demo: db<>fiddle
您需要 DISTINCT ON
过滤每个组的第一行。
SELECT DISTINCT ON (name)
*
FROM table
ORDER BY name, amount DESC
【讨论】:
【参考方案3】:您需要一个嵌套的内连接。试试这个 -
SELECT id, T2.name, T2.amount
FROM TABLE T
INNER JOIN (SELECT name, MAX(amount) amount
FROM TABLE
GROUP BY name) T2
ON T.amount = T2.amount
【讨论】:
当有 2 行名称相同、数量相同但日期和 ID 不同时,这将产生重复。以上是关于如何获取聚合函数选择的行的id? [复制]的主要内容,如果未能解决你的问题,请参考以下文章