Конкретный пример Oracle CONNECT_BY_ ROOT эквивалента в PostgreSQL - PullRequest
0 голосов
/ 18 апреля 2020

Я очень плох в Oracle, и теперь мне нужно преобразовать следующий Oracle 11 вид в Postgresql 12 вид.

  CREATE OR REPLACE FORCE VIEW "V_DESC_VALUE_HIERARCH_FULL" ("CHILD_VALUE_ID", "PARENT_VALUE_ID", "VALUE_LEVEL") AS 
  select  DESCRIPTOR_VALUE_ID as CHILD_VALUE_ID,
        CONNECT_BY_ROOT DESCRIPTOR_VALUE_ID as PARENT_VALUE_ID,
        LEVEL as VALUE_LEVEL
   from DESCRIPTOR_VALUE
connect by prior DESCRIPTOR_VALUE_ID = PARENT_VALUE_ID;

Все мои варианты PostgreSQL дают совершенно другой результат чем Oracle просмотр. Кто-нибудь может сказать, как его портировать?

Таблица значений дескриптора:

CREATE TABLE descriptor_value (
    descriptor_value_id bigint NOT NULL,
    descriptor_group_id bigint NOT NULL,
    full_value varchar(4000) NOT NULL,
    short_value varchar(250),
    value_code varchar(30),
    sort_order bigint NOT NULL,
    parent_value_id bigint,
    deleted smallint NOT NULL DEFAULT 0,
    portal smallint NOT NULL DEFAULT 0
) ;

1 Ответ

0 голосов
/ 18 апреля 2020

Обычный способ смоделировать connect_by_ root, это получить идентификатор root в нерекурсивной части и просто повторить его без изменений на протяжении рекурсивной части:

Я не уверен, насколько точно ваш иерархия построена (так как ваш запрос недействителен и не имеет смысла для меня).

Предположим, parent_value_id указывает на descriptor_value_id, тогда вы, вероятно, захотите что-то вроде этого:

WITH RECURSIVE cte AS (
  SELECT descriptor_value_id,
         parent_value_id,
         descriptor_value_id as root_id,
         1 as value_level
  FROM descriptor_value 
  WHERE parent_value_id IS NULL --<< you need some starting condition!

  UNION ALL

  SELECT c.descriptor_value_id,
         c.parent_value_id,
         p.root_id, --<< copy the root id to all rows
         p.value_level + 1
  FROM descriptor_value c 
   JOIN cte p ON c.parent_value_id = p.descriptor_value_id
) 
SELECT * 
FROM cte;
...