简体   繁体   English

在自引用表中排序

[英]Order by in a self-referencing table

Let's say I have the following table with data: 假设我有下表和数据:

+----+-----------+-----------+---------+
| 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       |
+----+-----------+-----------+---------+

Here's how it works: 以下是它的工作原理:

  • parent_id and prev_id are both foreign keys to id parent_idprev_id都是id外键
  • parent_id is used to differentiate between a section and sub-section (item) parent_id用于区分节和子节(项)
  • ie if parent_id is NULL, then it is a section; 即如果parent_id为NULL,那么它是一个部分; otherwise it is an item 否则它是一个项目
  • prev_id is used to indicate the last section or last item in the section prev_id用于表示该部分的最后一部分或最后一项
  • ie if the row is a section, then prev_id will point to the row of the previous section; 即如果行是一个部分,则prev_id将指向上一部分的行; if the row is an item, then prev_id will point to the row of the last item in the section 如果行是项目,则prev_id将指向该部分中最后一项的行
  • if prev_id is NULL, then it is the first section or first item in the section 如果prev_id为NULL,则它是该部分中的第一个部分或第一个项目
  • if parent_id and prev_id are both NULL, then it is the first section 如果parent_idprev_id都是NULL,那么它就是第一部分

So, is there a way to order it using SQL so that it looks like this: 那么,有没有办法使用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       |
+----+-----------+-----------+---------+

I would like so that 我想这样

  • The first section, followed by its items, appears at the top 第一部分及其项目显示在顶部
  • For each subsequent section, show the section followed by the items of that section 对于每个后续部分,请显示该部分的项目后面的部分

Edit: Here's a query that I came up with: 编辑:这是我提出的一个查询:

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

This version works: 这个版本有效:

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

There might be simpler versions around. 可能有更简单的版本。

Here is a SQL Fiddle (admittedly in Postgres, but that shouldn't make a difference for this problem). 是一个SQL小提琴(诚然在Postgres,但这不应该对这个问题产生影响)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM