mysql - 从聚合函数定义的列中选择值

标签 mysql sql

我目前正在为查询而苦苦挣扎,需要一些帮助。

我有两个表:

messages {
   ts_send,
   message,
   conversations_id
}

conversations {
   id
}

我想从每个对话中选择具有最新 ts_send 的消息。 因此,如果我进行了 3 次对话,我最终会收到 3 条消息。

我开始编写以下查询,但我对如何比较每个对话的 max(ts_send) 感到困惑。

SELECT c.id, message, max(ts_send) FROM messages m
JOIN conversations c ON m.conversations_id = c.id
WHERE c.id IN ('.implode(',', $conversations_ids).')
GROUP by c.id
HAVING max(ts_send) = ?';

也许查询一般是错误的,只是想分享我的尝试。

最佳答案

MySql 对 JOIN 的优化比相关子查询要好得多,因此我将介绍连接方法。

第一步是获取每次对话的最大ts_send:

SELECT  conversations_id, MAX(ts_send) AS ts_send
FROM    messages
GROUP BY conversations_id;

然后您需要将其JOIN 返回到消息表以获取实际消息。连接 conversation_id 和 MAX(ts_send) 确保每个对话只返回最新消息:

SELECT  messages.conversations_id,
        messages.message,
        Messages.ts_send
FROM    messages
        INNER JOIN
        (   SELECT  conversations_id, MAX(ts_send) AS ts_send
            FROM    messages
            GROUP BY conversations_id
        ) MaxMessage
            ON MaxMessage.conversations_id = messages.conversations_id
            AND MaxMessage.ts_send = messages.ts_send;

以上内容应该可以满足您的需求,除非您还需要在没有消息的情况下返回对话。在这种情况下,您需要从 conversations 和 LEFT JOIN 中选择上述查询:

SELECT  conversations.id,
        COALESCE(messages.message, 'No Messages') AS Message,
        messages.ts_send
FROM    conversations
        LEFT JOIN
        (   SELECT  messages.conversations_id,
                    messages.message,
                    Messages.ts_send
            FROM    messages
                    INNER JOIN
                    (   SELECT  conversations_id, MAX(ts_send) AS ts_send
                        FROM    messages
                        GROUP BY conversations_id
                    ) MaxMessage
                        ON MaxMessage.conversations_id = messages.conversations_id
                        AND MaxMessage.ts_send = messages.ts_send
        ) messages
            ON messages.conversations_id = conversations.id;

编辑

选择所有对话而不考虑他们是否有消息的后一种选择将更好地实现如下:

SELECT  conversations.id,
        COALESCE(messages.message, 'No Messages') AS Message,
        messages.ts_send
FROM    conversations
        LEFT JOIN messages
            ON messages.conversations_id = conversations.id
        LEFT JOIN
        (   SELECT  conversations_id, MAX(ts_send) AS ts_send
            FROM    messages
            GROUP BY conversations_id
        ) MaxMessage
            ON MaxMessage.conversations_id = messages.conversations_id
            AND MaxMessage.ts_send = messages.ts_send
WHERE   messages.ts_send IS NULL
OR      MaxMessage.ts_send IS NOT NULL;

在此感谢 spencer7593 , 谁提出了上述解决方案。

关于mysql - 从聚合函数定义的列中选择值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18237986/

相关文章:

sql - 在 PostgreSql 中计算百分比

mysql - 在mysql中返回具有重复列值的记录

php - 从mysql获取最新记录

MySQL 加载数据在最后一个字段上包含字符和字段终止符

mysql - 显示变量 mysql - 我在哪里可以找到这些参数的文件

javascript - 在表单上显示表单验证

mysql - 准备语句语法错误

PHP 上传带有变量名的文本文件

mysql - 表 'tbl_name' 被指定了两次,既作为 'UPDATE' 的目标又作为单独的数据源

sql - LIKE 和正则表达式之间的 PostgreSQL 性能差异