Реализация столбца сортировки в Postgres, который действует как связанный список - PullRequest
0 голосов
/ 02 мая 2018

Скажем, у меня есть таблица базы данных teams, в которой есть столбец порядка position, позиция может быть null, если это последний результат, или идентификатор следующего team, который расположен на единицу выше, чем эта команда. Это приведет к тому, что список будет всегда строго отсортирован (если вы используете целые числа, вам нужно управлять всеми другими значениями позиции при вставке нового team, то есть увеличивать их все на единицу), и вставка становится менее сложной ...

Но получить эту таблицу в виде отсортированного запроса оказалось непросто, вот где я сейчас нахожусь:

WITH RECURSIVE teams AS (  
  SELECT *, 1 as depth FROM team
  UNION
  SELECT t.*, ts.depth + 1 as depth
  FROM team t INNER JOIN teams ts ON ts.order = t.id 
SELECT
  id, order, depth
FROM
  teams
;

Что дает мне что-то вроде:

 id | order | depth
----+-------+-------
 53 |    55 |     1
 55 |    52 |     1
 55 |    52 |     2 
 52 |    54 |     2
 52 |    54 |     3
 54 |       |     3
 54 |       |     4

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

 id | order | depth
----+-------+-------
 53 |    55 |     1
 55 |    52 |     2 
 52 |    54 |     3
 54 |       |     4

Однако, похоже, я меняю запрос, который мне жаловался на применение GROUP BY как к id, так и к depth ... Как мне добраться из того места, где я сейчас нахожусь, туда, где я хочу быть?

1 Ответ

0 голосов
/ 02 мая 2018

Ваш рекурсивный запрос должен где-то начинаться (пока вы выбираете всю таблицу в первом подзапросе). Я предлагаю начать с последней записи, где столбец order равен нулю, и перейти к первой записи:

with recursive team(id, ord) as (values(53,55),(55,52),(52,54),(54,null)),
  teams as (
    select *, 1 as depth from team where ord is null -- select the last record here
    union all
    select t.*, ts.depth + 1 as depth
    from team t join teams ts on ts.id = t.ord) -- note that the JOIN condition reversed comparing to the original query
select * from teams order by depth desc; -- finally reverse the order
┌────┬──────┬───────┐
│ id │ ord  │ depth │
├────┼──────┼───────┤
│ 53 │   55 │     4 │
│ 55 │   52 │     3 │
│ 52 │   54 │     2 │
│ 54 │ ░░░░ │     1 │
└────┴──────┴───────┘
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...