Что эквивалентно синтаксису PostgreSQL для Oracle CONNECT BY START WITH?

В Oracle, если у меня есть таблица, определенная как …

CREATE TABLE taxonomy
    (
    key NUMBER(11) NOT NULL CONSTRAINT taxPkey PRIMARY KEY,
    value VARCHAR2(255),
    taxHier NUMBER(11)
    );
ALTER TABLE
    taxonomy
ADD CONSTRAINT
    taxTaxFkey
FOREIGN KEY
    (taxHier)
REFERENCES
    tax(key);

С этими значениями…

key value   taxHier
0   zero    null
1   one     0
2   two     0
3   three   0
4   four    1
5   five    2
6   six     2

Этот синтаксис запроса…

SELECT
     value
FROM
    taxonomy
CONNECT BY
    PRIOR key = taxHier
START WITH
    key = 0;

Даст …

zero
one
four
two
five
six
three

Как это делается в PostgreSQL?


person dacracot    schedule 22.07.2014    source источник
comment
Я думаю, вы захотите использовать С РЕКУРСОВЫМ   -  person Mike Christensen    schedule 23.07.2014
comment
stackoverflow.com/q/22626394/330315   -  person a_horse_with_no_name    schedule 23.07.2014


Ответы (3)


Используйте RECURSIVE CTE в Postgres:

WITH RECURSIVE cte AS (
   SELECT key, value, 1 AS level
   FROM   taxonomy
   WHERE  key = 0

   UNION  ALL
   SELECT t.key, t.value, c.level + 1
   FROM   cte      c
   JOIN   taxonomy t ON t.taxHier = c.key
   )
SELECT value
FROM   cte
ORDER  BY level;

Подробности и ссылки на документацию в моем предыдущем ответе:

person Erwin Brandstetter    schedule 22.07.2014
comment
Не могли бы вы указать мне здесь: stackoverflow.com/questions/62782512/? - person Pra_A; 07.07.2020

В Postgres есть аналог connect by. Вам нужно будет включить модуль. Он выключен по умолчанию.

Он называется tablefunc. Он поддерживает некоторые интересные функции перекрестных таблиц, а также знакомые функции «подключиться» и «Начать с». Я обнаружил, что он работает гораздо более красноречиво и логично, чем рекурсивный CTE. Если ваш администратор баз данных не может включить это, вам следует использовать способ, которым это делает Erwin.
Он достаточно надежен, чтобы также выполнять запрос типа "ведомость материалов".

Tablefunc можно включить, выполнив эту команду:

CREATE EXTENSION tablefunc;

Вот список полей подключения, взятый из официальной документации.

Parameter:         Description
relname:           Name of the source relation (table)
keyid_fld:         Name of the key field
parent_keyid_fld:  Name of the parent-key field
orderby_fld:       Name of the field to order siblings by (optional)
start_with:        Key value of the row to start at
max_depth:         Maximum depth to descend to, or zero for unlimited depth
branch_delim:      String to separate keys with in branch output (optional)

Вы действительно должны взглянуть на страницу документов. Это хорошо написано, и это даст вам варианты, к которым вы привыкли. (На странице документа прокрутите вниз, она ближе к низу.)

Расширение Postgreql "Connect by" Ниже приведено описание того, как разместить эту структуру вместе должно быть похоже. Существует масса возможностей, поэтому я не буду воздавать должное, но вот его фрагмент, чтобы дать вам представление.

connectby(text relname, text keyid_fld, text parent_keyid_fld
          [, text orderby_fld ], text start_with, int max_depth
          [, text branch_delim ])

Реальный запрос будет выглядеть так. Connectby_tree — это имя таблицы. Строка, начинающаяся с «AS», — это то, как вы называете столбцы. Он выглядит немного перевернутым.

SELECT * FROM connectby('connectby_tree', 'keyid', 'parent_keyid', 'pos', 'row2', 0, '~')
    AS t(keyid text, parent_keyid text, level int, branch text, pos int);
person Stradas    schedule 15.06.2016
comment
Как вы можете добавить больше столбцов в запрос? Скажем, мне нужны также имя, фамилия. - person Adrian Cosma; 05.07.2016

Как указано Stradas, я сообщаю о запросе:

SELECT value 
FROM connectby('taxonomy', 'key', 'taxHier', '0', 0, '~') 
AS t(keyid numeric, parent_keyid numeric, level int, branch text) 
inner join taxonomy t on t.key = keyid;
person sunrelax    schedule 03.04.2020