有没有办法在没有子选择的情况下执行以下查询?
SELECT * FROM
(
SELECT * FROM messaging_message WHERE recipient_id=4 ORDER BY timestamp DESC
) combined
GROUP BY thread_id HAVING status='unread'
表:
`messaging_message`
- id
- thread_id
- content
- sender_id
- recipient_id
- timestamp
- status
线程ID是消息的父线程。
更新:在测试目前为止的两个答案时,两个查询都没有生成我需要的结果。
查询应仅返回消息thread ='unread'中最新消息的结果。以下两个查询都返回了包含status ='unread'消息的任何线程的最顶层结果。
我要做的是像任何电子邮件收件箱,例如Gmail。假设收件箱在第一页上显示25个主题。我想强调那些具有status ='unread'的最新消息的线程(忽略任何早于最新消息的消息的状态)。
这也是我在订购结果上使用GROUP BY
的原因,因此我只能得到最新的结果,并且从这些结果中看出哪一个有状态='未读'
(请注意,我还将上述查询中的状态从“已删除”更改为“未读”,因此我可以更清楚地说明这一点。)
答案 0 :(得分:3)
你的查询是一个MySQL黑客攻击。 SQL标准不允许order by
处于该位置。我甚至不确定它是否会在MySQL中保持一致。话虽如此,您的版本相当清晰,并且可能优于更严格的版本。
例如,更正式的编写查询的方式是:
select *
from (
select distinct thread_id
from messaging_message
where recipient_id = 4
) thread
join messaging_message mm
on mm.id =
(
select mm2.id
from messaging_message mm2
where thead.thread_id = mm2.thread_id
order by
mm2.timestamp desc
limit 1
)
where mm.status = 'unread'
答案 1 :(得分:2)
所以要清楚,你试图在每个帖子中检索最近删除的邮件的详细信息,其中该邮件的收件人是user_id 4 ...是否正确?如果是这样,这个问题类似于你发布的问题here,似乎你已经将你的messagestatus表合并到你的消息表中了(好!)。所以这是我调整后的答案:
SELECT
b.*
FROM
messaging_messagethread a
INNER JOIN
messaging_message b ON a.id = b.thread_id
WHERE
b.timestamp =
(
SELECT MAX(timestamp)
FROM messaging_message
WHERE thread_id = a.id
)
AND b.status = 'unread'
AND b.recipient_id = 4
在这里,我们使用correlated subquery来提取每个帖子的最新消息的时间戳。
然后我们检查该消息的状态是否为“未读”。
最后,在WHERE子句的第三个条件中,我们只选择上次删除的消息的收件人为user_id 4的线程。