Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Составление SQL-запросов > группировка, сортировка и вывод дерева


Автор: slutsker 6.12.2012, 00:30
добрый день,
есть MySQL табличка категорий вида (у категории может быть категория родитель)

id | name | parent_id

пусть она имеет вид

 1 Статьи  0
 2 Спорт   1
 3 Авто     1
................
90 Налоги 1
91 Повести 0
92 Русские 91
93 Европейские 91
.........
120 Ремонт 1

как бы мне вывести записи из базы так, чтобы они были сгруппировали по parent_id и отсортированы по алфавиту
и стало так

Статьи
__Авто
__Налоги
__Ремонт
__Спорт
Повести
__Европейски
__Русские



Автор: Akina 6.12.2012, 07:53
Цитата(slutsker @  6.12.2012,  01:30 Найти цитируемый пост)
у категории может быть категория родитель

Максимальный уровень вложенности - фиксирован?

Автор: slutsker 6.12.2012, 10:28
максимальный уровень вложенности, в настоящий момент, фиксирован - у дочернего элемента не может быть дочернего элемента

это важное дополнение позволило решить задачу запросом вида
Код

SELECT id, name, parent_id FROM `cats` ORDER BY IF(parent_id>0, parent_id, id-0.5), name

(решение подсказал очень грамотный специалист, за это ему большое спасибо)

если вам известно, как это можно сделать для произвольного уровня вложенности средствами MySQL, пожалуйста, напишите

Автор: Akina 6.12.2012, 12:05
Цитата(slutsker @  6.12.2012,  11:28 Найти цитируемый пост)
как это можно сделать для произвольного уровня вложенности 

Просто изменить структуру хранения на ту, которая  предназначена для хранения и обработки деревьев. Скажем, Nested Set.

Добавлено через 5 минут и 41 секунду
Цитата(slutsker @  6.12.2012,  11:28 Найти цитируемый пост)
это важное дополнение позволило решить задачу запросом вида

Если в данных будут изменения, и у какой-то категории потомок будет иметь ID меньше, чем родитель (почему нет?) - запрос вывалит чушь.
Правильный вариант:
Код

SELECT
  id
, name
, parent_id 
FROM
  cats
ORDER BY 
  CASE WHEN parent_id=0 THEN id ELSE parent_id END
, parent_id=0 /* или parent_id!=0 ? лень думать... попробуй */
, name;

Автор: slutsker 6.12.2012, 13:27
странно,
проверил приведенный мною запрос на случай, когда id родителя меньше id сына - он работает

ваш запрос работает, но выдаёт в неправильном виде

__Авто
__Налоги
__Ремонт
__Спорт
Статьи
__Европейски
__Русские
Повести

Автор: Akina 6.12.2012, 16:31
Цитата(slutsker @  6.12.2012,  14:27 Найти цитируемый пост)
проверил приведенный мною запрос на случай, когда id родителя меньше id сына - он работает

Верно, я был невнимателен. Запрос действительно даст верную выборку.

Цитата(slutsker @  6.12.2012,  14:27 Найти цитируемый пост)
ваш запрос работает, но выдаёт в неправильном виде

Коммент прочитать и поправить лениво было? ну и не надо...

Автор: slutsker 6.12.2012, 21:55
вот с parent_id!=0 работает правильно (не понял ваш комментарий в первый раз)

спасибо за рекомендацию Nested Set

Автор: Akina 6.12.2012, 23:25
Цитата(slutsker @  6.12.2012,  22:55 Найти цитируемый пост)
вот с parent_id!=0 работает правильно 

Просто всегда забываю, в каких ЯП и СУБД True интерпретируется как 1, а в каких как -1...

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)