Php 根据表本身和不同的表对表输出进行排序

Php 根据表本身和不同的表对表输出进行排序,php,mysql,Php,Mysql,我有一个问题,我正在建立一个论坛,我遇到了以下问题 我有两张桌子 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 | t

我有一个问题,我正在建立一个论坛,我遇到了以下问题

我有两张桌子

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根本没有消息

我想按时间戳和别针订购。怎么做

->如果某个主题被固定,它必须位于顶部

->如果主题包含消息,请在最后一条消息的时间戳上排序

->如果主题没有任何消息,请在主题本身的标签上排序

在上面的示例中,顺序是(从上到下):

我希望我的问题足够清楚

希望有人能帮忙

提前谢谢

编辑:

我尝试了以下方法,但无效

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

您的任务很复杂,因为有许多消息附加到一个主题,您需要使用具有MAX(timestamp)的消息进行排序
DISTINCT
不起作用,因为它会从表中取出一条随机记录

我不得不使用子查询来解决这个问题<如果消息时间戳不为空,则code>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              |
+----------+---------+----------------------------------+

如有必要,请删除时间戳。我过去常显示查询获取正确的记录。

您尝试过什么吗?我们希望看到您在解决问题方面所做的努力。是的,我尝试了一些东西,我会将其添加到我的问题中,对您的代码进行了一点改进。您到底改进了什么?您能提供一个数据库结构和示例日期吗?我在sqlfiddle中玩,在没有子选择的情况下得到了相同的输出,但使用了修改后的ifnull部分
IFNULL(MAX(m.timestamp),t.timestamp)
@drot是的,我也找到了。但决定不作为答案,因为这是一个非标准SQL。@user4035。。。该死你让我开心(这很有效)。非常感谢!我把这件事搞了两天。谢谢,祝你今天愉快@用户4035啊,好的。我不是一个真正的SQL专家,一开始我也在考虑subselect,但当它在没有它的情况下工作时,我认为它可能有一些问题(例如,某些数据集的结果是错误的)。@Drott在ORDER BY中使用聚合函数可能是一个新问题。我查阅了维基百科,它说:“排序标准可以是表达式,包括列名、用户定义函数、算术运算或大小写表达式。”
+----------+---------+----------------------------------+
| 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              |
+----------+---------+----------------------------------+