Google BigQuery 中具有深度排序的广义数据透视表

Posted

技术标签:

【中文标题】Google BigQuery 中具有深度排序的广义数据透视表【英文标题】:Generalized Pivot Table with Deep Sort in Google BigQuery 【发布时间】:2017-02-17 20:44:23 【问题描述】:

这是Multi-level pivot in Google BigQuery 的后续问题,我想知道是否可以使用单个查询在 Google BigQuery 中构建嵌套数据透视表。确实如此,所以在这个后续问题中,我想探讨一般情况。

这是我正在使用的数据示例(也包含在此共享 Google Sheet 中):

现在,我想构建一个具有以下属性的数据透视表:

行和列级别的嵌套级别(上一个问题只有嵌套列) 行和列中的小计(以前只有总计) 多个指标(以前只有一个指标) 多种排序 - 按深度指标和字母顺序(以前没有任何排序条件) 限制(以前根本没有任何限制)

这是 Google 表格中内置的枢轴 --

这里的概念 SQL 语句是:

SELECT
    SUM(price),
    COUNT(price) 
BROKEN DOWN BY
    Studio (row),
    Title (row)
    Territory ID (col),
    Type (col)
SORTED/LIMITED BY
    Studio ==> A-Z, LIMIT 3,
    Title ==> SUM(price) in GRAND TOTAL DESC, LIMIT 4,
    Territory ID ==> COUNT(price) in Paramount TOTAL, LIMIT 2
    Type ==> A-Z, NO LIMIT

我不确定如何在概念上显示小计,但我们应该能够为每个细分字段指定这些。

是否可以在 Google BigQuery 的单个 SQL 语句中执行上述操作?生成它的步骤是什么?

【问题讨论】:

为了更好地理解问题 - 您能否解释一下为什么要在 BigQuery 中执行所有这些操作,而不是在演示 Google 表格中已有的相关数据透视工具中? @MikhailBerlyant 好吧,我们基本上是将数据导入 Excel 或 Google 表格,以便在小型查询中对其进行测试,并帮助我们更好地对其进行可视化。我们拥有的实际数据对于 Google 表格、Excel 或 PowerPivot 来说太大了。所以我们需要在数据库中做这个。 所以大多数情况下,您都在尝试最小化您为可视化工具带来的数据量 - 对吧?并且可视化本身仍然可以在该工具中完成。我对么?如果这是正确的 - 这将完全改变你现在对我的看法 @MikhailBerlyant 没错,我们正在尝试对数据进行透视,以便能够将其导出或在另一个工具中可视化。 我仍然迷路 - 为什么您需要在导出到工具之前对数据进行透视? pivot 是 Excel 或 Google Sheet 或 PowerPivot 等工具的一项重要功能!您根本不需要在 BigQuery 中执行此操作。我会理解您希望最小化在您的工具中使用的数据量 - 但这不需要旋转!如果旋转/可视化超出了您的问题范围 - 您的问题将变得合理实用且仍然具有挑战性,因此仍有思考和帮助您的空间。否则我认为它不实用 【参考方案1】:

。如果我们进行聚合并得到 1000 万个结果怎么办?除非我们在 bigquery 中应用限制等——传输的数据量会非常大……


让我们在这里澄清一下挑战:

所以通常,您会在后端运行类似下面的内容并将结果拉到可视化工具(前端)以进行进一步的操作,如排序、限制、旋转等。

#standardSQL
SELECT
  Studio, 
  Title, 
  TerritoryID,
  Type, 
  SUM(Price) AS Price, 
  COUNT(1) AS Volume
FROM YourTable  
GROUP BY Studio, Title, TerritoryID, Type   

正如您所提到的,在您的案例中,这样的结果很容易产生超过 1000 万行,并且您希望减小它的大小而不影响您在前端的数据透视/可视化中仍然呈现最终数据的能力强>


一个。建议/解决方案

下面展示了如何通过在后端应用排序和限制来实现这一点(因此结果大小大大减少),而不会失去进行透视的能力并仍然显示总计等。

让我们从简化的开始进入最终查询

初始查询(骨架)

让我们假设,根据已知标准,我们事先知道应该选择哪些工作室、标题、区域和类型 在这种情况下,下面的查询将返回所需的数据

#standardSQL
WITH Studios AS (
  SELECT 'Fox' 
  UNION ALL SELECT 'Paramouont' 
),
Titles AS (
  SELECT 'Fox' AS Studio,'Best Laid Plans' AS Title
  UNION ALL SELECT 'Fox','Homecoming'
  UNION ALL SELECT 'Paramount','Titanic'
  UNION ALL SELECT 'Paramount','Homecoming'
),
Territories AS (
  SELECT 'US' AS TerritoryID
  UNION ALL SELECT 'GB'
),
Totals AS (
  SELECT 
    IFNULL(b.Studio,'Other') AS Studio, 
    IFNULL(b.Title,'Other') AS Title, 
    IFNULL(c.TerritoryID,'Other') AS TerritoryID, 
    Type,
    ROUND(SUM(Price), 2) AS Price, COUNT(1) AS Volume
  FROM yourTable AS a 
  LEFT JOIN Titles AS b ON a.Studio = b.Studio AND a.Title = b.Title
  LEFT JOIN Territories AS c ON a.TerritoryID = c.TerritoryID
  GROUP BY Studio, Title, TerritoryID, Type
)
SELECT * FROM Totals
ORDER BY Studio, Title, TerritoryID, Type

输出将如下所示

Studio      Title           TerritoryID Type        Price    Volume  
Fox         Best Laid Plans GB          Movie         87.32    18    
Fox         Best Laid Plans GB          TV Episode    50.17    23    
Fox         Best Laid Plans Other       TV Episode  1131.0      2    
Fox         Best Laid Plans US          Movie        120.82    18    
Fox         Best Laid Plans US          TV Episode    53.76    24    
Fox         Homecoming      GB          TV Episode    60.22    28    
Fox         Homecoming      Other       TV Episode  2262.0      4    
Fox         Homecoming      US          TV Episode   128.45    58    
Other       Other           GB          Movie        142.71    29    
Other       Other           GB          TV Episode    84.8     40    
Other       Other           Other       Movie       3292.0      4    
Other       Other           Other       TV Episode  3282.0     16    
Other       Other           US          Movie         52.92     8    
Other       Other           US          TV Episode   233.05   101    
Paramount   Homecoming      GB          Movie         18.96     4    
Paramount   Homecoming      US          Movie        124.84    16    
Paramount   Titanic         GB          Movie         41.92     8    
Paramount   Titanic         Other       Movie         12.0      4    
Paramount   Titanic         US          Movie        139.84    16   

您可以轻松地将其反馈到您的 UI 中,以您需要的任何方式对其进行可视化

“最终”查询

现在,我们不再在所有相关维度中硬编码值 - 让我们为每个维度实施实际标准。 因此,以下查询(与上述骨架查询相比)的唯一变化在于以下 CTE:工作室、标题和领土

#standardSQL
WITH Studios AS (
  SELECT DISTINCT Studio 
  FROM yourTable 
  ORDER BY Studio LIMIT 3
),
Titles AS (
  SELECT Studio, Title 
  FROM (
    SELECT Studio, Title, ROW_NUMBER() OVER(PARTITION BY Studio ORDER BY PRICE DESC) AS pos
    FROM (SELECT Studio, Title, SUM(Price) AS Price FROM yourTable GROUP BY Studio, Title)
  ) WHERE pos <= 4
),
Territories AS (
  SELECT TerritoryID FROM yourTable  
  WHERE Studio = 'Paramount' GROUP BY TerritoryID
  ORDER BY COUNT(1) DESC LIMIT 2
),
Totals AS (
  SELECT 
    IFNULL(b.Studio,'Other') AS Studio, 
    IFNULL(b.Title,'Other') AS Title, 
    IFNULL(c.TerritoryID,'Other') AS TerritoryID, 
    Type,
    ROUND(SUM(Price), 2) AS Price, COUNT(1) AS Volume
  FROM yourTable AS a 
  LEFT JOIN Titles AS b ON a.Studio = b.Studio AND a.Title = b.Title
  LEFT JOIN Territories AS c ON a.TerritoryID = c.TerritoryID
  GROUP BY Studio, Title, TerritoryID, Type
)
SELECT * FROM Totals
WHERE NOT 'Other' IN (TerritoryID)
ORDER BY Studio, TerritoryID DESC, Type, Price DESC, Title

这里的结果是:

Studio      Title           TerritoryID Type        Price  Volume    
Fox         Best Laid Plans         US  Movie       120.82  18   
Fox         Titanic                 US  Movie        52.92   8   
Fox         1:00 P.M. - 2:00 P.M.   US  TV Episode  187.25  81   
Fox         Homecoming              US  TV Episode  128.45  58   
Fox         Best Laid Plans         US  TV Episode   53.76  24   
Fox         Best Laid Plans         GB  Movie        87.32  18   
Fox         Titanic                 GB  Movie        78.84  16   
Fox         1:00 P.M. - 2:00 P.M.   GB  TV Episode   61.42  28   
Fox         Homecoming              GB  TV Episode   60.22  28   
Fox         Best Laid Plans         GB  TV Episode   50.17  23   
Paramount   Titanic                 US  Movie       139.84  16   
Paramount   Homecoming              US  Movie       124.84  16   
Paramount   Titanic                 GB  Movie        41.92   8   
Paramount   Homecoming              GB  Movie        18.96   4   
Sony        Best Laid Plans         US  TV Episode   22.9   10   
Sony        Homecoming              US  TV Episode   22.9   10   
Sony        Best Laid Plans         GB  Movie        63.87  13   
Sony        Homecoming              GB  TV Episode   18.81   9   
Sony        Best Laid Plans         GB  TV Episode    4.57   3       

这里的重点是 - 虽然 BigQuery 在分析数十亿行和提取所需信息方面非常有效,但使用 BigQuery 实际定制结果数据以反映该结果的实际情况却非常低效呈现在客户端 UI 的表示层中。相反 - 你应该只将这些数据传递给 UI 并让你的可视化代码来处理它

【讨论】:

以上是关于Google BigQuery 中具有深度排序的广义数据透视表的主要内容,如果未能解决你的问题,请参考以下文章

使用 Google 表格作为具有重复字段的 BigQuery 数据源

如何从 Google bigquery(google-cloud-ruby gem)的视图表(具有 resource_full)中获取数据

尝试从 golang 广告读取/运行对 bigquery 的查询被拒绝访问:BigQuery BigQuery:未找到具有 Google Drive 范围的 OAuth 令牌

如何在 BigQuery 中对大表进行排序?

将具有 dtypes datetime64[ns] 和 timedelta64[ns] 的数据帧导入到 google bigquery 表

有没有办法在 Google Dataflow 中创建具有数据相关架构的 Bigquery 表?