【问题标题】:MySQL Order By Title then Grouped IDMySQL 按标题排序,然后分组 ID
【发布时间】:2019-09-17 21:06:21
【问题描述】:

我有一个表,其中包含可以按任务分组的任务。

我想知道是否有一种方法可以从表中选择任务,其顺序是将按标题排序的子任务直接放在按标题排序的父任务之下。永远只有一层子节点(即,任何行都不能有一个不在顶层的父节点)

下面是一个示例表和小提琴。在此示例中,所需的输出将是:

TaskID ParentTaskID Title
----------------------------------
6      NULL         A Task 3
1      NULL         Task 1
7      1            Task 1 A Sub 3
3      1            Task 1 Sub 1
4      1            Task 1 Sub 2
2      NULL         Task 2
5      2            Task 2 Sub 1

SQL Fiddle

CREATE TABLE `Tasks` (
  `TaskID` int(11) NOT NULL,
  `ParentTaskID` int(11) DEFAULT NULL,
  `Title` varchar(254) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

ALTER TABLE `Tasks`
  ADD PRIMARY KEY (`TaskID`);

ALTER TABLE `Tasks`
  MODIFY `TaskID` int(11) NOT NULL AUTO_INCREMENT;

  INSERT INTO `Tasks` (`TaskID`, `ParentTaskID`, `Title`) VALUES ('1', NULL, 'Task 1'), ('2', NULL, 'Task 2'), ('3', '1', 'Task 1 Sub 1'), ('4', '1', 'Task 1 Sub 2'), ('5', '2', 'Task 2 Sub 1'), ('6', NULL, 'A Task 3'), ('7', '1', 'Task 1 A Sub 3');

【问题讨论】:

    标签: mysql sql sql-order-by


    【解决方案1】:

    首先确保Task和Child被分组在一起,然后是null(父母),最后是孩子按标题排序

    SQL DEMO

    SELECT p.*, c.* 
    FROM Tasks as p
    JOIN Tasks as c
     ON c.ParentTaskID = p.TaskID
     OR (c.ParentTaskID IS NULL and p.TaskID = c.TaskID)
    ORDER BY p.Title
           , c.ParentTaskID
           , c.Title;
    

    输出

    +--------+--------------+----------+--------+--------------+----------------+
    | TaskID | ParentTaskID |  Title   | TaskID | ParentTaskID |     Title      |
    +--------+--------------+----------+--------+--------------+----------------+
    |      6 |              | A Task 3 |      6 |              | A Task 3       |
    |      1 |              | Task 1   |      1 |              | Task 1         |
    |      1 |              | Task 1   |      7 |            1 | Task 1 A Sub 3 |
    |      1 |              | Task 1   |      3 |            1 | Task 1 Sub 1   |
    |      1 |              | Task 1   |      4 |            1 | Task 1 Sub 2   |
    |      2 |              | Task 2   |      2 |              | Task 2         |
    |      2 |              | Task 2   |      5 |            2 | Task 2 Sub 1   |
    +--------+--------------+----------+--------+--------------+----------------+
    

    【讨论】:

    • 太棒了,谢谢。我将其更改为 ORDER BY Title, COALESCE(ParentTaskID, TaskID) , ParentTaskID , Title 以使顶级任务也按标题排序。
    • 好。我在完成答案后看到了这个要求,但不确定如何解决。
    • 其实这并没有解决,只是巧合地解决了示例数据集:(
    • 抱歉,这只是因为第一个标题旁边的所有标题都是“任务...”更改任何人并且不起作用。我认为您无法满足您想要的确切要求。我会考虑,但似乎并不容易。
    • 我做到了。我使用自加入来为孩子分配与父母相同的头衔。所以可以先按父标题排序。除了谦虚,我很好有时会吓到我:)
    【解决方案2】:

    在 MySQL 8+ 中,您可以使用 ORDER BY 中的窗口函数来执行此操作:

    SELECT *
    FROM Tasks
    ORDER BY MAX(CASE WHEN ParentTaskId IS NULL THEN Title END) OVER (PARTITION BY COALESCE(ParentTaskId, TaskId)),  -- parent title
             COALESCE(ParentTaskId, TaskId),  -- parent id in case titles match
             (ParentTaskId IS NULL) DESC,     -- parent first
             Title;
    

    Here 是一个 dbfiddle。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-11-10
      • 2019-07-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-17
      • 2019-06-06
      • 2016-01-15
      相关资源
      最近更新 更多