我有两个SQL表users
和messages
,如下所示:
user_id | username
--------|---------
1 | alice
2 | bob
3 | carol
message_id | sending_user_id | message | created_utc
-----------|-----------------|---------|-------------
1| 1 | a | 67
2| 1 | b | 68
3| 3 | c | 69
4| 2 | d | 70
5| 3 | e | 71
6| 1 | f | 72
我正在尝试编写一个SQL查询,该查询将导致message
除user
次{1}}所订购的每个created_utc
的最新message
。所以结果应该是这样的:
message_id | sending_user_id | message | created_utc | sending_username
-----------|-----------------|---------|-------------|----------------------
6| 1 | f | 72 | alice
5| 3 | e | 71 | carol
4| 2 | d | 70 | bob
我坚持如何使用以下查询保证邮件始终是最新的:
SELECT messages.message_id, messages.sending_user_id, messages.message, messages.created_utc, users.username AS sending_username
FROM messages
LEFT JOIN ON users
WHERE messages.sending_user_id=users.user_id
GROUP BY messages.sending_user_id
ORDER BY messages.created_utc DESC
编辑:我正在使用PostgreSQL 9.3.5
答案 0 :(得分:3)
对于Postgres,我建议distinct on
:
SELECT DISTINCT ON (m.sending_user_id) m.message_id, m.sending_user_id, m.message, m.created_utc,
u.username AS sending_username
FROM messages m LEFT JOIN
users u
on m.sending_user_id = u.user_id
ORDER BY m.sending_user_id, m.created_utc DESC;
如果您想要最终order by
,请使用子查询:
SELECT um.*
FROM (SELECT DISTINCT ON (m.sending_user_id) m.message_id, m.sending_user_id, m.message, m.created_utc,
u.username AS sending_username
FROM messages m LEFT JOIN
users u
on m.sending_user_id = u.user_id
ORDER BY m.sending_user_id, m.created_utc DESC
) um
ORDER BY created_utc;
答案 1 :(得分:0)
我认为最好(也是最灵活)的ANSI SQL解决方案是NOT EXISTS
:
SELECT m1.message_id, m1.sending_user_id, m1.message, m1.created_utc, users.username AS sending_username
FROM messages m1
LEFT JOIN users ON (m1.sending_user_id=users.user_id)
WHERE NOT EXISTS (
SELECT *
FROM messages m2
WHERE m2.sending_user_id = m1.sending_user_id
AND m2.created_utc < m1.created_utc
)