【问题标题】:How to link child and parent ids using BigQuery如何使用 BigQuery 链接子 ID 和父 ID
【发布时间】:2020-02-22 07:19:13
【问题描述】:

假设我有下表:

child_id   parent_id 
1          2
2          3
3          -
4          5
5          6
6          -
7          8

我想创建下表:

child_id   parent_id   branch_id
1          2           1
2          3           1
3          -           1
4          5           2
5          6           2
6          -           2
7          8           3

其中 branch_id 表示由 parent_id 链接在一起的分组。

但是,行顺序无法保证并且分支可能包含数百行。这排除了对 LAG() 函数的简单使用。

鉴于 BigQuery 的 SQL 的限制,我该如何实现这一目标?

【问题讨论】:

标签: sql google-bigquery parent-child


【解决方案1】:

以下示例说明如何针对此类情况使用 BigQuery 脚本

DECLARE rows_count, run_away_stop INT64 DEFAULT 0;

CREATE TEMP TABLE input AS 
  SELECT 1 child_id, 2 parent_id UNION ALL
  SELECT 2, 3 UNION ALL
  SELECT 3, NULL UNION ALL
  SELECT 4, 5 UNION ALL
  SELECT 5, 6 UNION ALL
  SELECT 6, NULL UNION ALL
  SELECT 7, 8 ;

CREATE TEMP TABLE ttt AS 
SELECT ARRAY(SELECT val FROM UNNEST([child_id, IFNULL(parent_id, child_id)]) val ORDER BY val ) arr FROM input;

LOOP
  SET (run_away_stop, rows_count) = (SELECT AS STRUCT run_away_stop + 1, COUNT(1) FROM ttt);

  CREATE OR REPLACE TEMP TABLE ttt AS
  SELECT ANY_VALUE(arr) arr FROM (
    SELECT ARRAY(SELECT DISTINCT val FROM UNNEST(arr) val ORDER BY val) arr
    FROM (
      SELECT ANY_VALUE(arr1) arr1, ARRAY_CONCAT_AGG(arr) arr    
      FROM (
        SELECT t1.arr arr1, t2.arr arr2, ARRAY(SELECT DISTINCT val FROM UNNEST(ARRAY_CONCAT( t1.arr, t2.arr)) val ORDER BY val) arr 
        FROM ttt t1, ttt t2 
        WHERE (SELECT COUNT(1) FROM UNNEST(t1.arr) val JOIN UNNEST(t2.arr) val USING(val)) > 0
      ) GROUP BY FORMAT('%t', arr1)
    )
  ) GROUP BY FORMAT('%t', arr);

  IF (rows_count = (SELECT COUNT(1) FROM ttt) AND run_away_stop > 1) OR run_away_stop > 10 THEN BREAK; END IF;
END LOOP;

SELECT input.*, branch_id
FROM input 
JOIN (
  SELECT ROW_NUMBER() OVER() AS branch_id, arr AS IDs FROM ttt
)
ON child_id IN UNNEST(IDs)

最终输出

Row child_id    parent_id   branch_id    
1   7           8           1    
2   4           5           2    
3   6           null        2    
4   5           6           2    
5   3           null        3    
6   2           3           3    
7   1           2           3    

【讨论】:

  • 了不起的 Mikhail,BigQuery 的功能比我想象的要强大得多。我将不得不花一些时间来了解它是如何工作的。
  • 您好@Mikhail Berlyant,当我将此代码应用于没有NULL 的问题时,我在此代码中收到“错误”。换句话说,数据中有很多链,但NULL不能用作指示链结束的信号。它应该解决这样的问题吗?
  • 我明白了。以上答案是根据您提供的具体问题和数据示例量身定制的。请发布新问题,其中包含您要应用的所有详细信息和逻辑,我很乐意回答。
  • 我会调查的:o)
  • 你好@Mikhail Berlyant 我一直在做一些进一步的测试,现在我相信你的算法工作正常,但我们的系统中有不可靠的数据。我也无法让您的代码因演示数据而失败,我非常努力!我将删除新的 stackoverflow 问题并感谢您的宝贵时间。
猜你喜欢
  • 1970-01-01
  • 2020-08-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-02
  • 1970-01-01
  • 2022-09-27
  • 1970-01-01
相关资源
最近更新 更多