如何在Big Query中透视表

use*_*472 10 google-bigquery

我正在使用Google Big Query,并且我正在尝试从公共示例数据集中获取透视结果.

对现有表的简单查询是:

SELECT * 
FROM publicdata:samples.shakespeare
LIMIT 10;
Run Code Online (Sandbox Code Playgroud)

此查询返回以下结果集.

在此输入图像描述

现在我要做的是,从表中获得结果,如果单词是勇敢的,选择"BRAVE"作为column_1,如果单词出席,选择"ATTENDED"作为column_2,并聚合单词计数对于这2.

这是我正在使用的查询.

SELECT
(CASE WHEN word = 'brave' THEN 'BRAVE' ELSE '' END) AS column_1,
(CASE WHEN word = 'attended' THEN 'ATTENDED' ELSE '' END) AS column_2,
SUM (word_count)
FROM publicdata:samples.shakespeare
WHERE (word = 'brave' OR word = 'attended')
GROUP BY column_1, column_2
LIMIT 10;
Run Code Online (Sandbox Code Playgroud)

但是,此查询返回数据

在此输入图像描述

我在寻找的是

在此输入图像描述

我知道这个数据集的这个数据集没有意义.但我只是以此为例来解释这个问题.如果你可以为我提供一些指示,那将是很棒的.

编辑:我还提到了如何使用BigQuery模拟数据透视表?它似乎也有我在这里提到的相同问题.

Fel*_*ffa 12

更新2019年:

由于这是一个很受欢迎的问题,让我更新到#standardSQL以及更一般的旋转案例.在这种情况下,我们有多行,每个传感器查看不同类型的属性.为了转动它,我们会做类似的事情:

#standardSQL
SELECT MoteName
  , TIMESTAMP_TRUNC(Timestamp, hour) hour
  , AVG(IF(SensorName LIKE '%altitude', Data, null)) altitude
  , AVG(IF(SensorName LIKE '%light', Data, null)) light
  , AVG(IF(SensorName LIKE '%mic', Data, null)) mic
  , AVG(IF(SensorName LIKE '%temperature', Data, null)) temperature
FROM `data-sensing-lab.io_sensor_data.moscone_io13`
WHERE MoteName = 'XBee_40670F5F'
GROUP BY 1, 2
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

作为一种替代AVG()你可以试试MAX(),ANY_VALUE()


以前:

我不确定你要做什么,但是:

SELECT NTH(1, words) WITHIN RECORD column_1, NTH(2, words) WITHIN RECORD column_2, f0_
FROM (
  SELECT NEST(word) words, SUM(c)  
  FROM (
    SELECT word, SUM(word_count) c
    FROM publicdata:samples.shakespeare
    WHERE word in ('brave', 'attended')
    GROUP BY 1
  )
)
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

更新:结果相同,查询更简单:

SELECT NTH(1, word) column_1, NTH(2, word) column_2, SUM(c)
FROM (
    SELECT word, SUM(word_count) c
    FROM publicdata:samples.shakespeare
    WHERE word in ('brave', 'attended')
    GROUP BY 1
)
Run Code Online (Sandbox Code Playgroud)


Ser*_*ron 7

2021 年更新:

BigQuery 中引入了一个新的PIVOT运算符。

在使用 PIVOT 将销售额和季度轮换为 Q1、Q2、Q3、Q4 列之前:

产品 销售量 四分之一
羽衣甘蓝 51 第一季度
羽衣甘蓝 23 Q2
羽衣甘蓝 45 Q3
羽衣甘蓝 3 第四季度
苹果 77 第一季度
苹果 0 Q2
苹果 25 Q3
苹果 2 第四季度

在使用 PIVOT 将销售额和季度轮换为 Q1、Q2、Q3、Q4 列后:

产品 第一季度 Q2 Q3 第四季度
苹果 77 0 25 2
羽衣甘蓝 51 23 45 3

询问:

with Produce AS (
  SELECT 'Kale' as product, 51 as sales, 'Q1' as quarter UNION ALL
  SELECT 'Kale', 23, 'Q2' UNION ALL
  SELECT 'Kale', 45, 'Q3' UNION ALL
  SELECT 'Kale', 3, 'Q4' UNION ALL
  SELECT 'Apple', 77, 'Q1' UNION ALL
  SELECT 'Apple', 0, 'Q2' UNION ALL
  SELECT 'Apple', 25, 'Q3' UNION ALL
  SELECT 'Apple', 2, 'Q4')
SELECT * FROM
  (SELECT product, sales, quarter FROM Produce)
  PIVOT(SUM(sales) FOR quarter IN ('Q1', 'Q2', 'Q3', 'Q4'))
Run Code Online (Sandbox Code Playgroud)

要动态构建列列表,请使用execute immediate

execute immediate (             
  select '''
    select * 
    from (select product, sales, quarter from Produce)
    pivot(sum(sales) for quarter in ("''' ||  string_agg(distinct quarter, '", "' order by quarter)  || '''"))
  '''
  from Produce
);
Run Code Online (Sandbox Code Playgroud)


Del*_*ace 5

还受到如何使用 BigQuery 模拟数据透视表的启发,使用 subselect 的以下请求会产生您想要的确切结果:

SELECT
  MAX(column_1),
  MAX(column_2),
  SUM(wc),
FROM (
  SELECT
  (CASE WHEN word = 'brave' THEN 'BRAVE' ELSE '' END) AS column_1,
  (CASE WHEN word = 'attended' THEN 'ATTENDED' ELSE '' END) AS column_2,
  SUM (word_count) AS wc
  FROM publicdata:samples.shakespeare
  WHERE (word = 'brave' OR word = 'attended')
  GROUP BY column_1, column_2
  LIMIT 10
)
Run Code Online (Sandbox Code Playgroud)

诀窍是MAX(NULL, 'ATTENDED', NULL, ...)等于'ATTENDED'.