如何在BigQuery中扩展透视?

时间:2016-01-18 00:50:45

标签: sql google-bigquery

让我们说,我有一天的音乐视频播放统计表mydataset.stats(3B行,1M用户,6K艺术家)。 简化的架构是: UserGUID String,ArtistGUID String

我需要从行到列的透视/转置艺术家,因此架构将是:
UserGUID String,Artist1 Int,Artist2 Int,... Artist8000 Int
随着艺术家的数量由各自的用户计数

How to transpose rows to columns with large amount of the data in BigQuery/SQL?How to create dummy variable columns for thousands of categories in Google BigQuery?中建议采用的方法,但看起来它不能扩展我的示例中的数字

这种方法可以缩放我的例子吗?

1 个答案:

答案 0 :(得分:8)

我尝试了以下方法,最多可以使用6000个功能,并且按预期工作。我相信它最多可以使用10K功能,这是表格中列数的硬限制

第1步 - 按用户/艺术家进行汇总

SELECT userGUID as uid, artistGUID as aid, COUNT(1) as plays 
FROM [mydataset.stats] GROUP BY 1, 2

第2步 - 规范化uid和辅助 - 因此它们是连续的数字1,2,3,......。
我们至少有两个原因需要这个:a)以后动态创建的sql尽可能紧凑,b)有更多可用/友好的列名

结合第一步 - 它将是:

SELECT u.uid AS uid, a.aid AS aid, plays 
FROM (
  SELECT userGUID, artistGUID, COUNT(1) AS plays 
  FROM [mydataset.stats] 
  GROUP BY 1, 2
) AS s
JOIN (
  SELECT userGUID, ROW_NUMBER() OVER() AS uid FROM [mydataset.stats] GROUP BY 1
) AS u ON u. userGUID = s.userGUID
JOIN (
  SELECT artistGUID, ROW_NUMBER() OVER() AS aid FROM [mydataset.stats] GROUP BY 1
) AS a ON a.artistGUID = s.artistGUID 

让我们将输出写入表格 - mydataset.aggs

第3步 - 一次使用已建议(在上述问题中)N个功能(艺术家)的方法。 在我的特定示例中,通过实验,我发现基本方法适用于2000到3000之间的许多功能。 为了安全起见,我决定一次使用2000个功能

下面的脚本用于动态生成查询,然后运行以创建分区表

SELECT 'SELECT uid,' + 
   GROUP_CONCAT_UNQUOTED(
      'SUM(IF(aid=' + STRING(aid) + ',plays,NULL)) as a' + STRING(aid) 
   ) 
   + ' FROM [mydataset.aggs] GROUP EACH BY uid'
FROM (SELECT aid FROM [mydataset.aggs] GROUP BY aid HAVING aid > 0 and aid < 2001)

上面的查询会产生另一个查询,如下所示:

SELECT uid,SUM(IF(aid=1,plays,NULL)) a1,SUM(IF(aid=3,plays,NULL)) a3,
  SUM(IF(aid=2,plays,NULL)) a2,SUM(IF(aid=4,plays,NULL)) a4 . . .
FROM [mydataset.aggs] GROUP EACH BY uid 

这应该运行并写入mydataset.pivot_1_2000

再次执行STEP 3(调整HAVING aid > NNNN and aid < NNNN)我们又增加了三个表mydataset.pivot_2001_4000mydataset.pivot_4001_6000
正如你所看到的那样 - mydataset.pivot_1_2000已经预期了架构但是从1到2001年的辅助功能; mydataset.pivot_2001_4000只有2001年至4000年的援助功能;等等

第4步 - 将所有分区数据透视表合并到最终数据透视表,所有功能在一个表中表示为列

与上述步骤相同。首先,我们需要生成查询然后运行它 所以,最初我们将“缝合”mydataset.pivot_1_2000和mydataset.pivot_2001_4000。然后用mydataset.pivot_4001_6000

结果
SELECT 'SELECT x.uid uid,' + 
   GROUP_CONCAT_UNQUOTED(
      'a' + STRING(aid) 
   ) 
   + ' FROM [mydataset.pivot_1_2000] AS x
JOIN EACH [mydataset.pivot_2001_4000] AS y ON y.uid = x.uid
'
FROM (SELECT aid FROM [mydataset.aggs] GROUP BY aid HAVING aid < 4001 ORDER BY aid)

应运行上面的输出字符串,并将结果写入mydataset.pivot_1_4000

然后我们重复步骤4,如下所示

SELECT 'SELECT x.uid uid,' + 
   GROUP_CONCAT_UNQUOTED(
      'a' + STRING(aid) 
   ) 
   + ' FROM [mydataset.pivot_1_4000] AS x
JOIN EACH [mydataset.pivot_4001_6000] AS y ON y.uid = x.uid
'
FROM (SELECT aid FROM [mydataset.aggs] GROUP BY aid HAVING aid < 6001 ORDER BY aid)

要写入mydataset.pivot_1_6000

的结果

结果表具有以下架构:

uid int, a1 int, a2 int, a3 int, . . . , a5999 int, a6000 int 

注意
一个即可。我尝试了这种方法,最多只有6000个功能,它按预期工作 的 B'/ strong>即可。步骤3和4中第二次/主要查询的运行时间从20到60分钟不等 <强> C 即可。重要提示:步骤3和4中的计费层从1到90不等。好消息是各个表的大小相对较小(30-40MB),因此计费字节也是如此。对于“2016年之前”项目,所有项目都被计为第1级,但在2016年10月之后,这可能是一个问题 有关详细信息,请参阅High-Compute queries中的Timing d 即可。以上示例显示了使用BigQuery进行大规模数据转换的强大功能!我认为(但我可能错了)存储物化特征矩阵不是最好的想法