Nic*_*own 2 sql join greatest-n-per-group
目前我正在两个表上执行左连接.第一个表有一个id和一个人名,第二个表有一个id,一个人的id来自表1,然后是一个时间戳(一个航班).
People Flights
id | name id | person_id | time
------------ ---------------------------
1 Dave 1 1 1284762115
2 Becky 2 1 1284787352
3 2 1284772629
4 2 1286432934
5 1 1283239480
Run Code Online (Sandbox Code Playgroud)
当我执行左连接时,我会得到一个人员列表和他们的航班时间,但我想要的只是具有最高ID的航班时间的人员列表
我一直在用
SELECT p.id, p.name max(f.time)
FROM People p
LEFT JOIN Flights f ON p.id = f.person_id
GROUP BY p.id, p.name
Run Code Online (Sandbox Code Playgroud)
但是,这只是给我最后的飞行时间,而不是上传到系统的最后一次飞行时间(即最高ID).
1 Dave 1284787352
2 Becky 1286432934
Run Code Online (Sandbox Code Playgroud)
重申一下,我想看看这个人的姓名,以及他们上次上传(最高身份证)航班时间的飞行时间.
1 Dave 1283239480
2 Becky 1286432934
Run Code Online (Sandbox Code Playgroud)
使用:
SELECT p.id,
p.name,
f.time
FROM PEOPLE p
JOIN FLIGHTS f ON f.person_id = p.id
JOIN (SELECT f.person_id,
MAX(f.id) AS max_id
FROM FLIGHTS f
GROUP BY f.person_id) x ON x.person_id = f.person_id
AND x.max_id = f.id
Run Code Online (Sandbox Code Playgroud)
如果您使用的是支持分析的数据库:
SELECT p.id,
p.name,
x.time
FROM PEOPLE p
JOIN (SELECT f.person_id,
f.time,
ROW_NUMBER() OVER(PARTITION BY f.person_id
ORDER BY f.id DESC) AS rk
FROM FLIGHTS f) x ON x.person_id = p.id
AND x.rk = 1
Run Code Online (Sandbox Code Playgroud)
如果你想要人,包括没有航班的人:
SELECT p.id,
p.name,
f.time
FROM PEOPLE p
LEFT JOIN FLIGHTS f ON f.person_id = p.id
JOIN (SELECT f.person_id,
MAX(f.id) AS max_id
FROM FLIGHTS f
GROUP BY f.person_id) x ON x.person_id = f.person_id
AND x.max_id = f.id
Run Code Online (Sandbox Code Playgroud)
......和分析版本:
SELECT p.id,
p.name,
x.time
FROM PEOPLE p
LEFT JOIN (SELECT f.person_id,
f.time,
ROW_NUMBER() OVER(PARTITION BY f.person_id
ORDER BY f.id DESC) AS rk
FROM FLIGHTS f) x ON x.person_id = p.id
AND x.rk = 1
Run Code Online (Sandbox Code Playgroud)