1

有没有办法在没有子选择的情况下进行以下查询?

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 是消息的父线程。

更新:到目前为止,在测试这两个答案时,两个查询都没有生成我需要的结果。

查询应仅返回消息线程中最新消息 = '未读' 的结果。以下两个查询都返回具有状态 = '未读' 的消息的任何线程的最顶层结果。

我正在尝试做的是类似于任何电子邮件收件箱的东西,例如 Gmail。假设收件箱在第一页显示 25 个线程。我只想突出显示状态为“未读”的最新消息的线程(忽略比最新消息更早的任何消息的状态)。

这也是我GROUP BY在排序结果上使用的原因,这样我只得到最新的结果,在这些结果中,看看哪个有 status='unread'

(请注意,我还将上述查询中的状态从“已删除”更改为“未读”,以便解释更清楚。)

4

2 回答 2

3

您的查询有点像 MySQL hack。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'
于 2012-06-10T07:31:16.487 回答
2

所以要清楚,您正在尝试在每个线程中检索该消息的收件人是 user_id 4 的最新删除消息的详细信息......对吗?如果是这样,这个问题类似于您在此处发布的问题,并且您似乎已将您的 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

在这里,我们使用相关子查询来提取每个线程的最新消息的时间戳。

然后我们检查该消息是否具有“未读”状态。

最后在 WHERE 子句的第三个条件中,我们只选择最后一条删除消息的接收者为 user_id 4 的线程。

于 2012-06-10T09:22:27.897 回答