我有一张purchases桌子:
-----------------
user_id | amount
-----------------
1 | 12
1 | 4
1 | 8
2 | 23
2 | 45
2 | 7
Run Code Online (Sandbox Code Playgroud)
我想要一个查询,每个返回一行user_id,但我想要的每个行user_id是每个amount最小的行user_id。所以我应该得到我的结果集:
-----------------
user_id | amount
-----------------
1 | 4
2 | 7
Run Code Online (Sandbox Code Playgroud)
DISTINCT在列上使用user_id可确保我不会得到重复的用户,但我不知道如何制作它,以便返回具有最少的 amount用户行。
您可以使用distinct on:
select distinct on (user) t.*
from t
order by user, amount;
Run Code Online (Sandbox Code Playgroud)
注意:如果您只想要最小的量,那么group by典型的解决方案是:
select user, min(amount)
from t
group by user;
Run Code Online (Sandbox Code Playgroud)
Distinct on是一种方便的 Postgres 扩展,可以轻松地为每组获取一行,而且它的性能通常比其他方法更好。
如果您的要求需要输出等于最小金额的行,例如表包含交易日期并且您在输出中需要它,那么一种方便的方法是使用row_number() over()选择所需的行。例如
CREATE TABLE mytable(
user_id INTEGER NOT NULL
,amount INTEGER NOT NULL
,trandate DATE NOT NULL
);
INSERT INTO mytable(user_id,amount,trandate) VALUES (1,12,'2020-09-12');
INSERT INTO mytable(user_id,amount,trandate) VALUES (1,4,'2020-10-02');
INSERT INTO mytable(user_id,amount,trandate) VALUES (1,8,'2020-11-12');
INSERT INTO mytable(user_id,amount,trandate) VALUES (2,23,'2020-12-02');
INSERT INTO mytable(user_id,amount,trandate) VALUES (2,45,'2021-01-12');
INSERT INTO mytable(user_id,amount,trandate) VALUES (2,7,'2021-02-02');
select
user_id, amount, trandate
from (
select user_id, amount, trandate
, row_number() over(partition by user_id order by amount) as rn
from mytable
) t
where rn = 1
Run Code Online (Sandbox Code Playgroud)
结果:
+---------+--------+------------+
| user_id | amount | trandate |
+---------+--------+------------+
| 1 | 4 | 2020-10-02 |
| 2 | 7 | 2021-02-02 |
+---------+--------+------------+
Run Code Online (Sandbox Code Playgroud)
在 db<>fiddle处对此进行演示
| 归档时间: |
|
| 查看次数: |
1335 次 |
| 最近记录: |