我有下一个数据:
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
答案 0 :(得分:2)
您需要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
\.
SELECT DISTINCT ON (name)
id, name, amount
FROM test
ORDER BY name, amount DESC, datefrom ASC;
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;
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