【问题标题】:MySql: need SQL query for sorting and grouping record sets in table by some rulesMySql:需要通过一些规则对表中的记录集进行排序和分组的 SQL 查询
【发布时间】:2012-03-04 11:39:24
【问题描述】:

在 MySql 我有表:

idPost | idPostParent | postText                              | dateCreated         |
1      | 1            |  This is parent post no1              | 2012-01-01 12:00:00 |
2      | 2            |  This is parent post no2              | 2012-01-02 13:00:00 |
3      | 1            |  This is first reply on idPost:1      | 2012-01-02 13:30:00 | 
4      | 4            |  This is parent post no3              | 2012-01-04 10:00:00 |
5      | 2            |  This is first reply on idPost:2      | 2012-01-04 11:00:00 |
6      | 1            |  This is second reply on idPost:1     | 2012-01-05 15:00:00 |
7      | 2            |  This is second reply on idPost:2     | 2012-01-06 17:00:00 |

注意:

  1. 如果 idPost = idPostParent 则检测到 PARENT 帖子
  2. 如果 idPost idPostParent 和回复是 detedted 回复帖子 与 idPostParent 中的帖子相关

需要 SQL 查询以按一些规则对表中的记录集进行排序和分组

  1. 帖子必须按 idPostParent 分组(先是父帖子,然后是其 回复)
  2. 最近输入或最近输入回复的 PARENT 帖子必须位于顶部。

结果集应该是:

idPost | idPostParent | postText                              | dateCreated         |
2      | 2            |  This is parent post no2              | 2012-01-02 13:00:00 |
5      | 2            |  This is first reply on idPost:2      | 2012-01-04 11:00:00 |
7      | 2            |  This is second reply on idPost:2     | 2012-01-06 17:00:00 |
1      | 1            |  This is parent post no1              | 2012-01-01 12:00:00 |
3      | 1            |  This is first reply on idPost:1      | 2012-01-02 13:30:00 |
6      | 1            |  This is second reply on idPost:1     | 2012-01-05 15:00:00 |
4      | 4            |  This is parent post no3              | 2012-01-04 10:00:00 |

原因: PARENT 帖子 idPost=2 是最新输入的回复帖子,因此它的帖子必须位于表格顶部。

感谢任何可能为解决方案做出贡献的人!

【问题讨论】:

  • 一般来说,您应该发布您尝试过的内容。这种类型的请求(“这就是我想要的,为我做”)是不合适的,并且可能会被否决。
  • 感谢您的建议!下次我会更小心的。

标签: mysql sql sorting grouping


【解决方案1】:

这适用于您的测试数据

SELECT
posts.*
FROM posts
INNER JOIN 
  (
    SELECT idPostParent, MAX(dateCreated) as dateLastAnswer
    FROM posts
    GROUP by idPostParent
  ) AS pp ON posts.idPostParent=pp.idPostParent
ORDER BY pp.dateLastAnswer DESC, idPost ASC

【讨论】:

    【解决方案2】:

    这是一种方法:

    SELECT p.*
    FROM posts p
    LEFT JOIN
     (SELECT idPostParent, MAX(dateCreated) AS time_of_newest
      FROM posts
      GROUP BY idPostParent) p2
     ON p.idPostParent = p2.idPostParent
    ORDER BY time_of_newest DESC, idPost=p.idPostParent DESC, dateCreated DESC
    

    解释:

    子查询

    SELECT idPostParent, MAX(dateCreated) AS time_of_newest
      FROM posts
      GROUP BY idPostParent
    

    选择每个“线程”创建的最大日期 (idPostParent)。

    这是LEFT JOINd 到主posts 表,因此每个线程都有一个用于该线程的time_of_newest

    我们按time_of_newest DESCENDING 排序(这将线程 2 放在线程 1 的前面,放在线程 4 的前面)。

    然后,我们按idPost=idPostParent1 DESC 排序,以便在回复前面获得父帖子(父帖子在这里有一个 1,回复都有一个 0,因为我们对降序的父帖子进行排序)。

    最后,我们按dateCreated DESC 排序,以便按顺序获得回复。

    【讨论】:

    • idPost=idPostParent1 DESCdateCreated DESC排序可以结合在idPost排序中,因为需要在回复之前创建父级。此外,您可以使用内部联接,因为 idPostParent 保证存在 - EXPLAIN 显示,INNER JOIN 将使用 idPostParent 上的索引,而 LEFT JOIN 不会
    • 亲爱的 Eugen 和 math.coffee,感谢您的解决方案。对我都有好处!太糟糕了,我只能将一个答案标记为已接受!
    【解决方案3】:

    这样的?

    SELECT op.*, (SELECT MAX(ip.dateCreated) FROM posts ip WHERE ip.idPostParent = op.idPostParent) newestParentReply 
    FROM posts op ORDER BY newestParentReply DESC, op.dateCreated ASC
    

    没有测试过。它的性能也会非常糟糕,使用必须为每个帖子执行的子查询。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-25
      • 2017-11-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多