如何在 BigQuery 的 SQL 查询中 link 这些行? (我认为这需要 CTE 递归,而 BigQuery 似乎不喜欢...)
How can I link these rows together in an SQL query in BigQuery? (I think this requires CTE recursion, which BigQuery doesn't seem to like...)
非常感谢任何帮助。完全被这个难住了! SQL 的业余爱好者,但我认为 BigQuery 没有帮到我。
我有一个看起来像这样的 table:
Object ID1 ID2
A 1 null
B 2 1
C 3 2
D 4 3
A、B、C、D其实是同一个对象。您可以看到它们由 "chain" 个子 ID 链接。 A 是 "master" 对象。
我想在此 table 中添加一个新列,其中 returns "A"(或等同物)用于链接对象(称为此 P1-Obj)。这是我希望输出的样子:
P1-Obj Object ID1 ID2
A A 1 null
A B 2 1
A C 3 2
A D 4 3
E E 5 null
E F 6 5
E G 7 6
E H 8 7
这必须与任意长度的 "chains" 一起使用(即可能有 0-100 个对象连接到 P1-Obj)。
我使用这个公式在电子表格中解决了这个问题 - 假设上面的 table 有 A-D 列,这个公式在放入 A 列时有效:=IF(ISBLANK($D2),$B2,INDIRECT ("A"&MATCH($D2,$C:$C,0)))。我需要 SQL 等价物!
到目前为止,我尝试使用带递归的 CTE 来开始使用数据结构,然后我可以使用它来完成上述操作。
类似于:
WITH cte as (
SELECT *
FROM table
where ID2 is null
UNION ALL
SELECT m.*
FROM table m
JOIN cte o
on m.ID1 = o.ID2)
select *
from cte
但 BigQuery 吐出:"Table name "table“缺少数据集,而请求中没有设置默认数据集”- 从快速 google 看来递归 CTE 不是BigQuery 支持。
我什至不确定递归 CTE 是否是我正在寻找的开始解决我的问题的正确方法,但我什至无法看到输出 - 以及所有其他 google 大道把我带到了死胡同
关于在 BigQuery 中是否有另一种方法(或通常使用 SQL),我很困惑!
非常感谢您的任何建议。
编辑:添加 fiddle:https://www.db-fiddle.com/f/m6EN38upDhFLt7eUwtKrLa/3
不确定这是否符合我的需要...
这个怎么样?
WITH RECURSIVE table2 (root_pn, pn, id1, id2) AS
(
SELECT pn as root_pn, pn, id1, id2
FROM table1
WHERE id2 IS NULL
UNION ALL
SELECT root_pn, c.pn, c.id1, c.id2
FROM table2 AS cp JOIN table1 AS c
ON cp.id1 = c.id2
)
SELECT * FROM table2
ORDER BY root_pn;
当您处理层次结构时,关卡闭包可能会起到作用。可以快速阅读它们 here
示例 fiddle 此处:https://www.db-fiddle.com/f/igzuLfJzsh7nmr2r3w5L5W/5
重点是创建一个包含所有祖先和后代的闭包 table,然后像这样使用它进行查询;
SELECT t2.pn as `p1-obj`, t1.pn, t1.id, t1.ancestor
FROM t1
JOIN t1_closure t1c ON t1.id = t1c.descendant
JOIN t1 t2 ON t1c.ancestor = t2.id
WHERE t1c.ancestor IN (1, 5);
以上是在您知道要查询的根节点的基础上进行的。您可以添加一个额外的子查询来计算根节点是什么,即
WHERE t1c.ancestor IN (
# Sub Query here
);
非常感谢任何帮助。完全被这个难住了! SQL 的业余爱好者,但我认为 BigQuery 没有帮到我。
我有一个看起来像这样的 table:
Object ID1 ID2
A 1 null
B 2 1
C 3 2
D 4 3
A、B、C、D其实是同一个对象。您可以看到它们由 "chain" 个子 ID 链接。 A 是 "master" 对象。
我想在此 table 中添加一个新列,其中 returns "A"(或等同物)用于链接对象(称为此 P1-Obj)。这是我希望输出的样子:
P1-Obj Object ID1 ID2
A A 1 null
A B 2 1
A C 3 2
A D 4 3
E E 5 null
E F 6 5
E G 7 6
E H 8 7
这必须与任意长度的 "chains" 一起使用(即可能有 0-100 个对象连接到 P1-Obj)。
我使用这个公式在电子表格中解决了这个问题 - 假设上面的 table 有 A-D 列,这个公式在放入 A 列时有效:=IF(ISBLANK($D2),$B2,INDIRECT ("A"&MATCH($D2,$C:$C,0)))。我需要 SQL 等价物!
到目前为止,我尝试使用带递归的 CTE 来开始使用数据结构,然后我可以使用它来完成上述操作。
类似于:
WITH cte as (
SELECT *
FROM table
where ID2 is null
UNION ALL
SELECT m.*
FROM table m
JOIN cte o
on m.ID1 = o.ID2)
select *
from cte
但 BigQuery 吐出:"Table name "table“缺少数据集,而请求中没有设置默认数据集”- 从快速 google 看来递归 CTE 不是BigQuery 支持。
我什至不确定递归 CTE 是否是我正在寻找的开始解决我的问题的正确方法,但我什至无法看到输出 - 以及所有其他 google 大道把我带到了死胡同
关于在 BigQuery 中是否有另一种方法(或通常使用 SQL),我很困惑!
非常感谢您的任何建议。
编辑:添加 fiddle:https://www.db-fiddle.com/f/m6EN38upDhFLt7eUwtKrLa/3
不确定这是否符合我的需要...
这个怎么样?
WITH RECURSIVE table2 (root_pn, pn, id1, id2) AS
(
SELECT pn as root_pn, pn, id1, id2
FROM table1
WHERE id2 IS NULL
UNION ALL
SELECT root_pn, c.pn, c.id1, c.id2
FROM table2 AS cp JOIN table1 AS c
ON cp.id1 = c.id2
)
SELECT * FROM table2
ORDER BY root_pn;
当您处理层次结构时,关卡闭包可能会起到作用。可以快速阅读它们 here
示例 fiddle 此处:https://www.db-fiddle.com/f/igzuLfJzsh7nmr2r3w5L5W/5
重点是创建一个包含所有祖先和后代的闭包 table,然后像这样使用它进行查询;
SELECT t2.pn as `p1-obj`, t1.pn, t1.id, t1.ancestor
FROM t1
JOIN t1_closure t1c ON t1.id = t1c.descendant
JOIN t1 t2 ON t1c.ancestor = t2.id
WHERE t1c.ancestor IN (1, 5);
以上是在您知道要查询的根节点的基础上进行的。您可以添加一个额外的子查询来计算根节点是什么,即
WHERE t1c.ancestor IN (
# Sub Query here
);