2015-04-23 48 views
1

給定一個表標籤組(SQL的BigQuery如果可能的話)

 name ip 
A = |A  1 | 
    |B  1 | 
    |C  1 | 
    |B  2 | 
    |C  2 | 
    |D  3 | 
    |E  2 | 

如果有兩個人的名字,他們共享同組屬於同一個IP。另外同名的IP也屬於同一組。如果您找到ip 1,{A,B,C}的所有名稱,那麼您應該將與{A,B,C}相關的所有ips包含在同一個組{1,2}中,然後再將所有名稱與這些ips還沒有包含{E}等等。在這個特定的例子中,{A,B,C,E} x {1,2}中的任何內容都在同一個組中。對於上表中的結果將是

 name ip group 
A = |A  1  1 | 
    |B  1  1 | 
    |C  1  1 | 
    |B  2  1 | 
    |C  2  1 | 
    |D  3  2 | 
    |E  2  1 | 

只是要清楚:

如果名字A,B和C都是IP 1然後將它們組合在一起,你應該有

A, 1 = group1 
B, 1 = group1 
C, 1 = group1 

如果名字A,B也共享IP 2,那麼他們不應該建立新組,而是應該要在同一個組這樣的:

A, 1 = group1 
B, 1 = group1 
C, 1 = group1 
A, 2 = group1 
B, 2 = group1 

目標是在Google BigQuery SQL中解決這個問題。

到目前爲止,我有

select ip, row_number() over() as group, 
GROUP_CONCAT(name,',') as names, 
from A 
group by ip 

它產生的所有名稱爲IP並讓一組,但沒有找到的所有IP地址的名稱或找到組包含所有所有對名字和ips。

請注意,您可以使用split來訪問連接的名稱(在本例中爲',')。

更新 - 這被稱爲傳遞閉包。如果這太困難了,那麼就足以說明如何進行傳遞閉包的第一次迭代(如何找到與每個ip相關聯的所有名稱相關聯的所有ips)並將它們標記爲組。

+0

你在找什麼不聚類分析。相反,你需要什麼被稱爲**傳遞閉包**。在SQL查詢中無法做到這一點。相反,你需要能夠做迭代或遞歸的東西。 –

+0

是的 - 我同意你不能解決一個需要SQL收斂的問題,但我正在尋找一個近似值 - 換句話說,如何計算第一個傳遞組(所以連接所有的名字,然後所有的ips名)。然後我可以在sql中重複這個迭代N次(其中N相當小),並稱它「足夠接近」。 – cgnorthcutt

+0

嚴格地說,傳遞閉包對於關係代數來說是不可能的,但對SQL來說是可能的 - 使用WITH RECURSIVE子句。但這主要是理論上的,因爲BigQuery不支持這樣的子句。 –

回答

2

這是我第一次迭代的解決方案。它有點長,可能會有所改進,但這就是我所擁有的。

步驟1.

select name, nest(ip) ips, group_concat(string(ip)) sip from 
(select 'a' name, 1 ip), 
(select 'b' name, 1 ip), 
(select 'c' name, 1 ip), 
(select 'b' name, 2 ip), 
(select 'c' name, 2 ip), 
(select 'd' name, 3 ip), 
(select 'e' name, 2 ip) 
group by name 

商店的結果在臨時表X

步驟2.

select a.name name, group_concat(b.name) as cluster from (
select a.name, b.name from (
select a.*, b.* from dataset.x a cross join dataset.x b 
) omit record if every(not b.sip contains string(a.ips)) 
group by 1, 2 order by 1, 2) group by 1 

商店的結果在臨時表ÿ

步驟3.

select cluster from (
select group_concat(part) cluster from (
select name, part from (
select a.name name, split(b.cluster) part 
from dataset.y a cross join dataset.y b 
where b.cluster contains a.name) group by 1, 2 order by 1, 2) 
group by name) group by cluster 

這將產生所有獨特的集羣,即

a,b,c,e 
d 
+0

感謝您的嘗試。然而,人們事先並不知道名稱是'a','b','c','d','e'(並且可能有成千上萬個名字),因此您將無法使用這些關鍵字在您的查詢中。 – cgnorthcutt

+0

我沒有在解決方案中使用列'name'的實際值。第一個查詢說明如何使用與您的示例中相同的數據集。實際上,您將使用輸入表。 –

+0

啊 - 我會試試這個,回到你的投票和修改我的意見後,成功/失敗:) – cgnorthcutt