我想使用BigQuery生成图的connected components。
给出下面的图(以连接的节点对表示):
(E1, E2)
(E2, E3)
(E3, E4)
(E4, E5)
我们可以得出结论,所有这些组件都是连接的,因此代表一个连接的组件:
(E1, E2, E3, E4, E5)
以下是用于生成图的连接部分的传统算法:Breadth-first search和Depth-first search
我最初的想法是重新创建匹配的节点对,以使所有实体最终都指向一个公共节点(通过使子节点指向其祖先节点)。因此,如果(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中这可能吗?
答案 0 :(得分:0)
您可以尝试将ROW_NUMBER
与窗口功能配合使用。
什么是窗口功能。
OVER (
[ <PARTITION BY clause> ]
[ <ORDER BY clause> ]
[ <ROW or RANGE clause> ]
)
确定在应用关联的窗口函数之前行集的分区和顺序。即,OVER子句定义查询结果集中的窗口或用户指定的行集。然后,窗口函数会为窗口中的每一行计算一个值。
因此您可以通过Entity1
SELECT Entity1,
ROW_NUMBER() OVER(partition by Entity1) Group
FROM T
答案 1 :(得分:0)
您需要的是递归联接: https://en.wikipedia.org/wiki/Recursive_join
但是由于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;
一旦停止更改-您就完成了。