在自引用表中排序

时间:2016-05-01 15:37:33

标签: mysql sql sql-order-by

我们说下面有数据表:

+----+-----------+-----------+---------+
| id | name      | parent_id | prev_id |
+----+-----------+-----------+---------+
| 1  | Section 1 | NULL      | NULL    |
| 2  | Item 1.1  | 1         | NULL    |
| 3  | Item 1.2  | 1         | 2       |
| 4  | Item 1.3  | 1         | 3       |
| 5  | Section 2 | NULL      | 1       |
| 6  | Item 2.1  | 5         | NULL    |
| 7  | Item 2.2  | 5         | 6       |
| 8  | Item 2.3  | 5         | 7       |
| 9  | Item 1.4  | 1         | 4       |
+----+-----------+-----------+---------+

以下是它的工作原理:

  • parent_idprev_id都是id
  • 的外键
  • parent_id用于区分部分和子部分(项目)
  • 即。如果parent_id为NULL,那么它是一个部分;否则它是一个项目
  • prev_id用于表示
  • 部分中的最后一部分或最后一项
  • 即。如果该行是一个部分,那么prev_id将指向上一部分的行;如果该行是项目,则prev_id将指向
  • 部分中最后一项的行
  • 如果prev_id为NULL,则它是
  • 部分中的第一部分或第一部分
  • 如果parent_idprev_id都是NULL,则它是第一部分

那么,是否有办法使用SQL对其进行排序,使其如下所示:

+----+-----------+-----------+---------+
| id | name      | parent_id | prev_id |
+----+-----------+-----------+---------+
| 1  | Section 1 | NULL      | NULL    |
| 2  | Item 1.1  | 1         | NULL    |
| 3  | Item 1.2  | 1         | 2       |
| 4  | Item 1.3  | 1         | 3       |
| 9  | Item 1.4  | 1         | 4       | <---
| 5  | Section 2 | NULL      | 1       |
| 6  | Item 2.1  | 5         | NULL    |
| 7  | Item 2.2  | 5         | 6       |
| 8  | Item 2.3  | 5         | 7       |
+----+-----------+-----------+---------+

我想这样

  • 第一部分及其项目显示在顶部
  • 对于每个后续部分,请显示该部分的项目后面的部分

修改:这是我提出的查询:

SELECT id, name, parent_id, prev_id FROM
((
    SELECT id, name, parent_id, prev_id, id AS some_id
    FROM learning_paths
    WHERE parent_id IS NULL
)
UNION ALL
(
    SELECT id, name, parent_id, prev_id, parent_id AS some_id
    FROM learning_paths
    WHERE parent_id IS NOT NULL
)) t
ORDER BY t.some_id, prev_id

1 个答案:

答案 0 :(得分:2)

此版本有效:

order by coalesce(parentid, id),
         (parentid is null) desc,
         coalesce(previd, parentid, id),
         previd,
         id

可能有更简单的版本。

Here是一个SQL小提琴(诚然在Postgres中,但不应该对这个问题产生影响)。