PostgreSQL:返回按外键列分组的最新行

时间:2018-08-29 22:17:36

标签: sql postgresql greatest-n-per-group

我有一个与此表类似的表:

credit
+---------+----------------+-------------+--------------+-------------------------+
| id (PK) | person_id (FK) | transaction | total credit |        date_time        |
+---------+----------------+-------------+--------------+-------------------------+
|     345 |              1 |       -1.00 |        34.50 | 2018-08-29 12:00:00.000 |
|     897 |              1 |        5.45 |        39.95 | 2018-08-29 12:34:00.000 |
|     378 |              2 |        0.01 |         0.01 | 2018-08-29 08:00:00.000 |
|     789 |              2 |       20.00 |        20.01 | 2018-08-29 09:00:00.000 |
+---------+----------------+-------------+--------------+-------------------------+

我将如何在Postgres中编写查询以仅返回表中每个唯一date_time DESC分组的最新(按person_id行)?

+---------+----------------+-------------+--------------+-------------------------+
| id (PK) | person_id (FK) | transaction | total credit |        date_time        |
+---------+----------------+-------------+--------------+-------------------------+
|     897 |              1 |        5.45 |        39.95 | 2018-08-29 12:34:00.000 |
|     789 |              2 |       20.00 |        20.01 | 2018-08-29 09:00:00.000 |
+---------+----------------+-------------+--------------+-------------------------+

2 个答案:

答案 0 :(得分:1)

使用distinct on

select distinct on (person_id) t.*
from t
order by person_id, date_time desc

答案 1 :(得分:1)

您可以尝试一下。 在窗口中使用带有窗口功能的ROW_NUMBER来使行号被person_id分割,并在子查询中按date_time进行排序,然后得到行号为1

CREATE TABLE credit(
   id int,
   person_id int,
   transaction float,
   "total credit" float,
   date_time timestamp
);

INSERT INTO credit values (345,1 ,-1.00,34.50, '2018-08-29 12:00:00.000');
INSERT INTO credit values (897,1 ,5.45 ,39.95, '2018-08-29 12:34:00.000');
INSERT INTO credit values (378,2 ,0.01 ,0.01 , '2018-08-29 08:00:00.000');
INSERT INTO credit values (789,2 ,20.00,20.01, '2018-08-29 09:00:00.000');

查询1

SELECT * FROM (
    SELECT *,ROW_NUMBER() OVER (PARTITION BY person_id  ORDER BY date_time DESC) rn
    FROM credit
) t1
where rn = 1

Results

|  id | person_id | transaction | total credit |            date_time | rn |
|-----|-----------|-------------|--------------|----------------------|----|
| 897 |         1 |        5.45 |        39.95 | 2018-08-29T12:34:00Z |  1 |
| 789 |         2 |          20 |        20.01 | 2018-08-29T09:00:00Z |  1 |