2016-05-01 3 views
0

Допустим, у меня есть следующая таблица с данными:Сортировка в таблице автореферентное

+----+-----------+-----------+---------+ 
| 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_id и prev_id являются внешние ключи к id
  • parent_id используется для разграничения между разделом и подсектором (позиция)
  • т.е. если parent_id является NU LL, то это раздел; в противном случае это элемент
  • prev_id используется для указания последнего раздела или последний элемент в секции
  • т.е. если строка представляет собой сечение, то prev_id будет указывать на строку предыдущего раздела; если строка является элементом, то prev_id будет указывать на строку последнего элемента в разделе
  • , если prev_id этого значения NULL, то это первая секция или первый элемент в разделе
  • , если parent_id и prev_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 
+0

Какой у вас запрос до сих пор? – piyushj

ответ

2

Эта версия работает:

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

Возможны более простые варианты.

Here - это скрипт SQL (по общему признанию, в Postgres, но это не должно иметь значения для этой проблемы).

+0

К сожалению, ни одно из утверждений не создает желаемый результат. – Mikey

+0

@Mikey. , , Он исправлен и протестирован. Кажется, я попытался сделать короткое сокращение в первый раз. –

Смежные вопросы