Использование рекурсии с самостоятельным внешним ключом - PullRequest
0 голосов
/ 12 февраля 2019

Я использую PostgreSQL 10, и у меня есть следующая структура:

Тип таблицы с внешним ключом к себе.

    id  name   parent_id
    1  namea    Null
    2  nameb    Null
    3  namea1   1
    4  namea11  3 
    5  namea111 4 
    6  nameb1   2 
    7  nameb2   2

Таблица Item_Type для многихотношение ко многим

   id type_id item_id
   1    1      1
   2    3      2
   3    5      3
   4    7      4

Элемент таблицы, который имеет отношение M2M к типу.

 id   name 
  1  item1   
  2  item2   
  3  item3   
  4  item4   

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

Мне интересно, не проще ли попробовать PostgreSQL recursion.

Я проверил документацию, но не очень хорошо понял, потому что получаю ошибку, и не понимаю почему.

WITH RECURSIVE descendants AS (
 SELECT id, name FROM Type WHERE id = 1
 UNION
 SELECT t.id, t.name, t.parent_id FROM Type AS t
 INNER JOIN descendants AS d ON d.id = t.parent_id
) SELECT * FROM descendants;

ОШИБКА: каждый запрос UNIONдолжно иметь одинаковое количество столбцов

Что мне нужно - Предоставление имени типа:

1) Получить все имена / идентификаторы для запрошенного Type и потомков

2) Получить все Item для запрошенных Type и потомков, а также число Item на Type и потомков

Например:

Еслизапрашиваемое имя типа 'namea1', я должен получить для идентификаторов типов 1,3,4,5 и для идентификаторов элементов 1,2,3

1 Ответ

0 голосов
/ 12 февраля 2019

Ошибка говорит само за себя.Ваш союз делится на:

  • SELECT <2 fields> from Type ...
  • SELECT <3 fields> from Type JOIN Descendant ...

Просто выберите 3 поля на обеих половинах:

WITH RECURSIVE descendants AS (
 SELECT id, name, parent_id FROM Type WHERE id = 1
 UNION
 SELECT t.id, t.name, t.parent_id FROM Type AS t
 INNER JOIN descendants AS d ON d.id = t.parent_id
) SELECT * FROM descendants;
...