我想使用 BigQuery 生成图表的“连接组件”。 给出下图(由连接的节点对表示):
(E1, E2)
(E2, E3)
(E3, E4)
(E4, E5)
我们可以得出结论,所有这些组件都是连接的,因此代表一个连接的组件:
(E1, E2, E3, E4, E5)
以下是用于生成图的连通分量的传统算法:广度优先搜索
和深度优先搜索 我最初的想法是重新创建匹配的节点对,以便所有实体最终都指向一个公共节点(通过使子节点指向其祖先节点)。因此,如果 (E1, E2) 是一对并且 (E2, E3) 是一对。我可以编写 SQL 逻辑来创建一个新对 (E1, E3),然后我可以丢弃 (E2, E3)。
这是一个更深入的示例:输入:
(E1, E2)
(E2, E3)
(E3, E4)
(E4, E5)
迭代 1:
(E1, E2)
(E1, E3) which replaces (E2, E3)
(E2, E4) which replaces (E3, E4)
(E3, E5) which replaces (E4, E5)
迭代 2:
(E1, E2)
(E1, E3)
(E1, E4) which replaces (E2, E4)
(E1, E5) which replaces (E3, E5)
我很快意识到,当图很大时,这个过程需要很长时间,因为我们一次只执行一跳。
是否可以根据 BigQuery 表中的给定匹配对更快地生成连接组件?
输入:
|--------------------|------------------|
| Entity 1 | Entity 2 |
|--------------------|------------------|
| E1 | E2 |
|--------------------|------------------|
| E2 | E3 |
|--------------------|------------------|
| E3 | E4 |
|--------------------|------------------|
| E4 | E5 |
|--------------------|------------------|
所需输出:
我想编写一个查询,读取上面的输入表并输出以下内容:
|--------------------|------------------|
| Entity | Group |
|--------------------|------------------|
| E1 | 1 |
|--------------------|------------------|
| E2 | 1 |
|--------------------|------------------|
| E3 | 1 |
|--------------------|------------------|
| E4 | 1 |
|--------------------|------------------|
| E5 | 1 |
|--------------------|------------------|
这在 BigQuery 中可能吗?
:现在支持递归 CTE,因此这个答案大部分已过时。 但是由于 BigQuery 并不直接支持这一点, 你能做的就是重复将表与其自身连接起来, 创建一个新的连接组件表并执行此操作 直到组件数量不再变化。
类似:
select a, min(if(c > a, a, c)) c
from (select x.a, y.c from data x join data y on x.c = y.a)
group by a;
这将根据其自身值和连接值的 id 的最小值为每个值分配组件 id
c
。
每次运行后,检查select count(distinct c) from data;
一旦停止变化 - 你就完成了。