我的SQL查询有问题
我有表message
和表recipient
message
是
ID author date
--------------------
0 1 2013-07-08 05:38:47
1 1 2013-07-13 05:38:47
2 1 2013-07-15 05:38:47
3 1 2013-07-15 05:38:47
4 2 2013-07-17 05:38:47
5 1 2013-07-28 05:38:47
recipient
是
ID m_id recipient
--------------------
0 0 2
1 1 2
2 2 3
3 3 2
4 4 1
5 5 2
我需要从表message
返回行,并使用表recipient
中的收件人列,其中最后一个日期位于message
表中
我会试试这个
SELECT m.*
FROM message as m
INNER JOIN recipient as r ON (m.ID = r.m_id)
WHERE m.author = 1
GROUP BY r.recipient
ORDER BY m.ID DESC
返回
ID author date
--------------------
2 1 2013-07-15 05:38:47
0 1 2013-07-08 05:38:47
但我需要
ID author date
--------------------
5 1 2013-07-28 05:38:47
2 1 2013-07-15 05:38:47
请帮助
我使用MySQL Server 5.1
我找到了解决问题的方法
SELECT m.*
FROM (
SELECT * FROM recipient
WHERE 1=1
ORDER BY recipient.ID DESC
) AS r
INNER JOIN message AS m ON (r.m_id = m.ID)
WHERE m.author = 1
GROUP BY r.recipient
只需反向表recipient
答案 0 :(得分:2)
非常简单快速的 PostgreSQL 与DISTINCT ON
- 非标准SQL,因此在每个RDBMS中都不可用。
问题没有提到它,但是从代码示例中得出它实际上是为每个收件人“strong> 寻找给定author
即可。
SELECT DISTINCT ON (r.recipient) m.*
FROM message m
JOIN recipient r ON r.m_id = m.id
WHERE m.author = 1
ORDER BY r.recipient, m.date DESC, r.m_id -- to break ties
详细信息以及多个SQL标准备选方案:
Select first row in each GROUP BY group?
使用基本标准SQL的另一种解决方案。适用于所有主要的RDBMS,包括 MySQL (因为已添加该标记):
SELECT m.*
FROM message m
JOIN recipient r ON r.m_id = m.id
WHERE m.author = 1
AND NOT EXISTS (
SELECT 1
FROM message m1
JOIN recipient r1 ON r1.m_id = m1.id
WHERE r1.recipient = r.recipient
AND m1.author = 1
AND m1.date > m.date
)
只有具有最新日期的行才能通过NOT EXISTS
反半连接。
答案 1 :(得分:1)
假设您正在使用SQL-Server,您可以使用ranking function之类的ROW_NUMBER
:
WITH CTE AS(
SELECT m.*,
RN=ROW_NUMBER()OVER(PARTITION BY r.recipient ORDER BY m.date DESC)
FROM message as m
INNER JOIN recipient as r ON (m.ID = r.m_id)
WHERE m.author = 1
)
SELECT * FROM CTE WHERE RN = 1