如何在大查询中显示父子关系的完整层次结构

How can the complete hierarchy of the parent child relation ship be shown in big query

一些背景--- 我有两个 table 一 - table 列出系统中的所有实体, 另一个指定实体之间的关系

问-- 问题是查看 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' ;

上面的清单 'mapp' 包含所有实体(类型 - app 是最终父级)并且 rel table 包含关系。

我可以得到类似下面的输出吗

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

好的,在网上搜索和尝试多种选择之后,我想出了很多办法,花了很多时间来了解细节,但我想我已经找到了解决方案。也许它会为人们省去我所经历的麻烦。我会尽量解释

-- 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);

已经使用数组和结构,因为它们更容易玩。并且 bigquery 脚本已用于循环。失控条件可以增加,如果人们期望很多级别。

这是最终输出

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

希望它能帮助下线的人进行类似的练习。