如何获取由汇总函数选择的行的ID?

时间:2018-09-28 08:20:12

标签: postgresql aggregate-functions

我有下一个数据:

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

但是我需要ID为3的数量包含8

id | name | amount
-----------
3  | a    |  8
5  | b    |  1

这可能吗?

PS。这是开票任务所必需的。在某天2018-01-15的{​​{1}}的配置已更改,用户消耗了10h的资源a,并在14h休息– 8。我需要用最大值来计算这样的一天。因此,在2018-01-15天,带有3的行将被忽略。 (在第二天2018年1月16日,我将向id = 4开具账单)
因此,我为该行计费:

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选择的行

UPD
我将任务解析为:

max

UPD
使用window functions

会更好

3 个答案:

答案 0 :(得分:2)

demo: db<>fiddle

您需要DISTINCT ON来过滤每个组的第一行。

SELECT DISTINCT ON (name) 
    * 
 FROM table 
 ORDER BY name, amount DESC

答案 1 :(得分:2)

至少有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)

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 :(得分:0)

您需要嵌套的内部联接。试试这个-

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