Хорошо. Итак, после большой борьбы с поиском 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
Надеюсь, что это поможет кому-то выполнить аналогичное упражнение.