使用Google Big Query组织电子表格使用的Edgelist

时间:2017-08-22 13:31:33

标签: sql excel google-bigquery

我在尝试重新组织一个我从Gephi导出为.csv的大型边缘列表时遇到了麻烦。

数据的结构是:

  • 两栏,"来源"和"目标"。
  • "来源"包含用户ID,目标包含人口统计信息,如城市,国家和大学。
  • 由于数据的结构,用户可能会被复制到"来源"如果他们有多个人口统计记录。

例如:

Source      Target

user142     cityA

user532     countryA

user352     cityC

user532     cityA

user143     countryC

user532     university1

我想要的输出是为每个唯一用户定位在他们自己的行上,为#34; City"," Country"和"" University" - 像这样:

Unique User    City     Country     University

user142        CityA

user532        CityA    CountryA    University1

user352        CityC

user143                 CountryC

我已经能够使用以下索引,匹配和数组公式,使用多个步骤将边缘列表分成Excel中的所需输出。但是这很冗长,当涉及大的边缘列表时,Excel经常会崩溃。

Excel流程:

第1步:

=INDEX($A$2:$A$5819, MATCH(0, COUNTIF($D$1:$D1, $A$2:$A$5819), 0))

这会过滤所有用户的唯一记录(colA)并将其放在新列(colD)中。

第2步:

=ArrayFormula(IFERROR(INDEX($B$2:$B$174, MATCH(0, COUNTIF($D2:D2,$B$2:$B$174)+IF($A$2:$A$174<>$D2, 1, 0), 0)), 0))

向下看&#34;目标&#34;列(B),针对步骤1(colD)中创建的列中的唯一用户。但是,这不会按列对输出进行排序。因此从左到右可以为每个独特的用户阅读城市,国家,大学或国家,大学,城市等。

第3步:

=transpose(sort(transpose(E2:H2)))

然后,此步骤按字母顺序对列进行排序,因此左右列读取城市,国家/地区,大学。

我的主要问题是这是一个缓慢且手动的过程,因此我希望在Big Query中使用SQL来尽可能提高效率。

有关如何开始构建Query以将数据排序为所需输出的任何信息都将受到高度赞赏。

我已经有一些SQL经验,但主要是文本提取和正则表达式。

谢谢!

2 个答案:

答案 0 :(得分:1)

在BigQuery中,您可以使用条件聚合来完成此操作。它看起来像这样:

select source,
       max(case when type = 'City' then target end) as city,
       max(case when type = 'Country' then target end) as country,
       max(case when type = 'University' then target end) as university
from demographics d
group by source;

您的问题未指定type之类的列。但如果您有不同类型的信息,似乎需要一个。

答案 1 :(得分:0)

正如Gordon评论的那样,您可以使用ARRAY_AGG将所有这些信息聚合在一起。例如:

#standardSQL
SELECT
  Source,
  ARRAY_AGG(IF(REGEXP_CONTAINS(Target, r'^ci'), Target, NULL) IGNORE NULLS) City,
  ARRAY_AGG(IF(REGEXP_CONTAINS(Target, r'^co'), Target, NULL) IGNORE NULLS) Country,
  ARRAY_AGG(IF(REGEXP_CONTAINS(Target, r'^uni'), Target, NULL) IGNORE NULLS) Universiry
FROM
  `your_table`
GROUP BY
  Source

使用模拟数据:

#standardSQL
WITH data AS(
  SELECT 'user142' AS Source, 'cityA' AS Target UNION ALL
  SELECT 'user532', 'countryA' UNION ALL
  SELECT 'user 352', 'cityC' UNION ALL
  SELECT 'user532', 'cityA' UNION ALL
  SELECT 'user143', 'countryC' UNION ALL
  SELECT 'user532', 'university1' UNION ALL
  SELECT 'user532', 'cityB'
)

SELECT
  Source,
  ARRAY_AGG(IF(REGEXP_CONTAINS(Target, r'^ci'), Target, NULL) IGNORE NULLS) City,
  ARRAY_AGG(IF(REGEXP_CONTAINS(Target, r'^co'), Target, NULL) IGNORE NULLS) Country,
  ARRAY_AGG(IF(REGEXP_CONTAINS(Target, r'^uni'), Target, NULL) IGNORE NULLS) Universiry
FROM
  data
GROUP BY
  Source