Sql Postgres-按用户分组行,每个组中每个用户返回一行
我有一张购物桌: 我需要一个查询,该查询将为每个用户\u id返回一行,但我想要为每个用户\u id返回的行的数量是每个用户\u id最小的。因此,我应该得到以下结果集:Sql Postgres-按用户分组行,每个组中每个用户返回一行,sql,postgresql,Sql,Postgresql,我有一张购物桌: 我需要一个查询,该查询将为每个用户\u id返回一行,但我想要为每个用户\u id返回的行的数量是每个用户\u id最小的。因此,我应该得到以下结果集: ----------------- user_id | amount ----------------- 1 | 4 2 | 7 在“用户id”列上使用D
-----------------
user_id | amount
-----------------
1 | 4
2 | 7
在“用户id”列上使用DISTINCT可确保不会获得重复的用户id,但我不知道如何使其以最少的数量返回用户行。您可以在:
注意:如果您只需要最小的数量,则分组方式将是典型的解决方案:
select user, min(amount)
from t
group by user;
Distinct on是一个方便的Postgres扩展,可以轻松地为每个组获取一行,而且它的性能通常优于其他方法。如果您的要求需要输出一行,该行等于最小的金额,例如,表中包含一个交易日期,并且您需要在输出中使用该行,然后一个方便的方法是使用row_number over来选择所需的行。e、 g
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
结果:
+---------+--------+------------+
| user_id | amount | trandate |
+---------+--------+------------+
| 1 | 4 | 2020-10-02 |
| 2 | 7 | 2021-02-02 |
+---------+--------+------------+
在dbfiddle上演示这一点为什么不使用select user_id,按用户id从采购组中装载。这不是更有效吗?诚实的问题
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
+---------+--------+------------+
| user_id | amount | trandate |
+---------+--------+------------+
| 1 | 4 | 2020-10-02 |
| 2 | 7 | 2021-02-02 |
+---------+--------+------------+