如何使用标准版或遗留sql

时间:2018-05-11 13:31:30

标签: sql google-bigquery

我想从表中获取两列并创建一个交叉表,以查看每个客户在哪个产品类别中购买了多少产品。 以下是我的表中的示例数据:

Row     Customer_ID     Style    
 1      MEM014          BLS87    
 2      KAR810          DR126    
 3      NIKE61          MMQ5     
 4      NIKE61          MMQ5     
 5      STT019          BLS83    
 6      STT019          BLS84    
 7      STT019          BLS87    

我想得到这样的结果表:

Customer - DR126 - MMQ5 - BLS83 - BLS84 - BLS87
MEM014       0       0      0       0       1
KAR810       1       0      0       0       0
NIKE61       0       2      0       0       0
STT019       0       0      1       1       1   

2 个答案:

答案 0 :(得分:2)

以下是BigQuery Standard SQL

      

第1步 - 生成透视查询

  #standardSQL
  SELECT CONCAT(
  "SELECT Customer_ID,", 
  STRING_AGG(CONCAT("COUNTIF(Style='", Style, "') ", Style)), 
  " FROM `project.dataset.your_table` GROUP BY Customer_ID ORDER BY Customer_ID")
  FROM (
    SELECT DISTINCT Style
    FROM `project.dataset.your_table`
    ORDER BY Style
  )    

如果您使用下面的问题中的虚拟数据运行

  #standardSQL
  WITH `project.dataset.your_table` AS (
    SELECT 'MEM014' Customer_ID, 'BLS87' Style UNION ALL    
    SELECT 'KAR810', 'DR126' UNION ALL    
    SELECT 'NIKE61', 'MMQ5' UNION ALL     
    SELECT 'NIKE61', 'MMQ5' UNION ALL     
    SELECT 'STT019', 'BLS83' UNION ALL    
    SELECT 'STT019', 'BLS84' UNION ALL    
    SELECT 'STT019', 'BLS87' 
  )
  SELECT CONCAT(
  "SELECT Customer_ID,", 
  STRING_AGG(CONCAT("COUNTIF(Style='", Style, "') ", Style)), 
  " FROM `project.dataset.your_table` GROUP BY Customer_ID")
  FROM (
    SELECT DISTINCT Style
    FROM `project.dataset.your_table`
    ORDER BY Style
  )

您将获得以下数据透视查询

SELECT Customer_ID,COUNTIF(Style='BLS83') BLS83,COUNTIF(Style='BLS84') BLS84,COUNTIF(Style='BLS87') BLS87,COUNTIF(Style='DR126') DR126,COUNTIF(Style='MMQ5') MMQ5 FROM `project.dataset.your_table` GROUP BY Customer_ID

第2步 - 运行生成的数据透视查询

如果你针对你的虚拟数据运行它 - 你会得到预期的结果

Row Customer_ID BLS83   BLS84   BLS87   DR126   MMQ5     
1   KAR810      0       0       0       1       0    
2   MEM014      0       0       1       0       0    
3   NIKE61      0       0       0       0       2    
4   STT019      1       1       1       0       0      

注1 :上面假设您的样式名称符合列名约定(示例中的那些)。如果不是 - 您将需要转义不支持的字符等(步骤1的简单调整)
注2 :最大未解析查询长度为256 KB。因此,如果您的样式名称与示例中的样式名称相似 - 上面的解决方案将支持大约8500个样式,对于表格中的列数,该样式应该小于限制(10K?)

答案 1 :(得分:1)

您可以使用条件聚合:

select customer,
       sum(case when style = 'DR126' then 1 else 0 end) as DR126,
       sum(case when style = 'MMQ5' then 1 else 0 end) as MMQ5,
       . . .
from t
group by customer;

如果您有完整的样式列表,则此方法有效。如果没有,那么你应该考虑结果集的数组。

编辑:

如果更适合您的目的,您可以创建一个结构数组:

select customer, array_agg(cs) as styles
from (select customer, style, count(*) as cnt
      from t
      group by customer
     ) cs
group by customer;

您不能做的是让查询返回可变数量的列。为此,您需要动态SQL和编程语言。