我有一个问题,我正在建立一个论坛,我遇到了以下问题。
我有2张桌子
table: topics
topic_id | name | timestamp | pinned
-------------------------------------------------
1 | topic_1 | 2016-01-01 12:00:00 | 0
2 | topic_2 | 2016-01-01 13:00:00 | 0
3 | topic_3 | 2016-01-01 14:00:00 | 1
4 | topic_4 | 2016-01-01 15:00:00 | 0
5 | topic_5 | 2016-01-01 16:00:00 | 0
table: messages
message_id | topic_id | text | timestamp
---------------------------------------------------
1 | 1 | test | 2016-01-01 12:30:00
2 | 2 | test | 2016-01-01 13:30:00
3 | 2 | test | 2016-01-01 13:45:00
4 | 1 | test | 2016-01-01 14:30:00
5 | 4 | test | 2016-01-01 17:30:00
正如您所看到的,主题#1有2条消息,主题#2也有2条消息,主题#4 1条消息,主题#3和#5根本没有消息。
我想在PINNED和TIMESTAMP上订购它们。怎么样?
- >如果某个主题被固定,那么它必须位于顶部
- >如果主题有消息,请在最后消息的时间戳上对它们进行排序
- >如果主题没有任何消息,请在主题本身的时间戳上对它们进行排序
上面的例子,顺序是(从上到下):
topic_3 (pinned so ALWAYS at the top)
topic_4 (last message at 17:00:00)
topic_5 (no messages but started at 16:00:00)
topic_1 (last message at 14:30:00)
topic_2 (last message at 13:45:00)
我希望我的问题很清楚。
希望有人可以提供帮助!
提前致谢。
编辑:
我尝试了以下但是这不起作用
SELECT DISTINCT
t.topic_id,
t.name
FROM
topics AS t
LEFT JOIN messages AS m ON m.topic_id = t.topic_id
ORDER BY
t.pinned DESC,
m.timestamp DESC,
t.timestamp DESC
答案 0 :(得分:1)
由于一个主题附加了许多消息,您需要使用具有MAX(时间戳)的消息进行排序,因此您的任务变得复杂。 DISTINCT
因为从表中取出随机记录而无法工作。
我不得不使用子查询来解决问题。如果消息时间戳不为NULL,则IFNULL
将返回消息时间戳,否则为 - 任务所需的主题时间戳。
SELECT
t.topic_id,
t.name,
IFNULL(m.timestamp, t.timestamp)
FROM
topics AS t
LEFT JOIN
(SELECT
messages.topic_id,
MAX(messages.timestamp) as timestamp
FROM
messages
GROUP BY
messages.topic_id
) AS m
ON m.topic_id = t.topic_id
GROUP BY
t.topic_id
ORDER BY
t.pinned DESC,
IFNULL(m.timestamp, t.timestamp) DESC;
输出:
+----------+---------+----------------------------------+
| topic_id | name | IFNULL(m.timestamp, t.timestamp) |
+----------+---------+----------------------------------+
| 3 | topic_3 | 2016-01-01 14:00:00 |
| 4 | topic_4 | 2016-01-01 17:30:00 |
| 5 | topic_5 | 2016-01-01 16:00:00 |
| 1 | topic_1 | 2016-01-01 14:30:00 |
| 2 | topic_2 | 2016-01-01 13:45:00 |
+----------+---------+----------------------------------+
如有必要,删除时间戳,我曾经表明查询会获取正确的记录。