Как полная иерархия родительских дочерних отношений может быть показана в большом запросе? - PullRequest
0 голосов
/ 19 апреля 2020

Немного предыстории --- У меня есть две таблицы. В одной таблице перечислены все сущности в системе, в другой - отношения между сущностями

Ask - Запрос - это просмотр таблиц, можем ли мы наметить Отношение каждого дочернего объекта к родительскому.

- Что я сделал

CREATE TEMP TABLE rell AS 
  SELECT 3 child_id, 2 parent_id UNION ALL
  SELECT 2, 1 UNION ALL
  SELECT 4, 1 UNION ALL
  SELECT 6, 2 UNION ALL
  SELECT 14, 6 UNION ALL
    SELECT 15, 14 UNION ALL
  SELECT 7, 8 UNION ALL
  SELECT 8, 5 UNION ALL
  SELECT 9, 10 UNION ALL
  SELECT 11, 12 ;

CREATE TEMP TABLE mapp AS 
  SELECT 1 item_id, 'app' type UNION ALL
  SELECT 2 , 'ci'  UNION ALL
  SELECT 3 , 'ci'  UNION ALL
  SELECT 4 , 'ci'  UNION ALL
  SELECT 5 , 'app'  UNION ALL
  SELECT 6 , 'ci'  UNION ALL
  SELECT 7 , 'ci'  UNION ALL
  SELECT 8 , 'ci'  UNION ALL
  SELECT 9 , 'app'  UNION ALL
  SELECT 10 , 'ci'  UNION ALL
  SELECT 11 , 'ci'  UNION ALL
  SELECT 14 , 'ci'  UNION ALL
  SELECT 15 , 'ci'  UNION ALL
  SELECT 12 , 'ci' ;

В приведенном выше листинге 'mapp' есть все сущности (тип - app - последний родитель), а в таблице rel есть отношения.

Могу ли я получить что-то вроде ниже

original_child  final_parent    path
4   1   4>1
3   1   3>2>1
7   5   7>8>5
14  1   14>6>2>1
15  1   15>14>6>2>1
11  12  11>12
2   1   2>1
8   5   8>5
6   1   6>2>1

1 Ответ

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

Хорошо. Итак, после большой борьбы с поиском inte rnet и опробованием нескольких вариантов, вот что я придумал, потребовалось много времени, чтобы понять детали, но я думаю, что нашел решение. Может быть, это спасет людей от неприятностей, которые я пошел, хотя. Я попытаюсь объяснить, как я go

-- Initialise variables 
DECLARE steps INT64 DEFAULT 1;
DECLARE table_holder ARRAY<STRUCT<original_child INT64, latest_parent INT64,path STRING>>;

--- Set up dummy tables 

CREATE TEMP TABLE rell AS 
  SELECT 3 child_id, 2 parent_id UNION ALL
  SELECT 2, 1 UNION ALL
  SELECT 4, 1 UNION ALL
  SELECT 6, 2 UNION ALL
  SELECT 14, 6 UNION ALL
    SELECT 15, 14 UNION ALL
  SELECT 7, 8 UNION ALL
  SELECT 8, 5 UNION ALL
  SELECT 9, 10 UNION ALL
  SELECT 11, 12 ;

CREATE TEMP TABLE mapp AS 
  SELECT 1 item_id, 'app' type UNION ALL
  SELECT 2 , 'ci'  UNION ALL
  SELECT 3 , 'ci'  UNION ALL
  SELECT 4 , 'ci'  UNION ALL
  SELECT 5 , 'app'  UNION ALL
  SELECT 6 , 'ci'  UNION ALL
  SELECT 7 , 'ci'  UNION ALL
  SELECT 8 , 'ci'  UNION ALL
  SELECT 9 , 'app'  UNION ALL
  SELECT 10 , 'ci'  UNION ALL
  SELECT 11 , 'ci'  UNION ALL
  SELECT 14 , 'ci'  UNION ALL
  SELECT 15 , 'ci'  UNION ALL
  SELECT 12 , 'ci' ;


  SET table_holder = (
            SELECT ARRAY_AGG(STRUCT(a.item_id,
            b.parent_id,    CONCAT(CAST(a.item_id AS STRING),">",CAST(b.parent_id AS STRING)))
            ) cls from mapp a inner join rell b  on a.item_id = b.child_id where a.type!='app') ;




    LOOP 
   SET table_holder = (
   SELECT ARRAY_AGG(STRUCT(a.original_child,
      coalesce(b.parent_id,a.latest_parent),   coalesce( CONCAT(path,">",CAST(b.parent_id AS STRING)),path))
      ) cls from UNNEST (table_holder) a left outer join rell b  on a.latest_parent = b.child_id ) ;  

  SET steps = steps+1;
  IF steps=5 THEN LEAVE; END IF;

    END LOOP;


   SELECT * from UNNEST (table_holder);

Массивы и структура были использованы, так как с ними легче играть. и большой цикл сценариев был использован для цикла. Состояние бегства может быть увеличено, если люди ожидают много уровней.

Вот окончательный результат

original_child  final_parent    path
4   1   4>1
3   1   3>2>1
7   5   7>8>5
14  1   14>6>2>1
15  1   15>14>6>2>1
11  12  11>12
2   1   2>1
8   5   8>5
6   1   6>2>1

Надеюсь, что это поможет кому-то выполнить аналогичное упражнение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...