【问题标题】:How to unpivot in BigQuery?如何在 BigQuery 中取消透视?
【发布时间】:2015-03-06 02:21:15
【问题描述】:

不确定要调用什么函数,但转置是我能想到的最接近的方法。

我在 BigQuery 中有一个配置如下的表:

但我想查询这样配置的表:

用于创建此表的 SQL 代码是什么样的?

谢谢!

【问题讨论】:

    标签: sql google-bigquery transpose unpivot


    【解决方案1】:

    2020 年更新fhoffa.x.unpivot()

    见:

    我创建了一个公共持久 UDF。如果您有一个表 a,您可以将整行提供给 UDF 以使其不被透视:

    SELECT geo_type, region, transportation_type, unpivotted
    FROM `fh-bigquery.public_dump.applemobilitytrends_20200414` a
      , UNNEST(fhoffa.x.unpivot(a, '_2020')) unpivotted
    

    它像这样转换表格:

    进入这个


    正如评论所提到的,我上面的解决方案不能解决问题。

    所以这里有一个变体,而我看看如何将所有内容整合为一个:

    CREATE TEMP FUNCTION unpivot(x ANY TYPE) AS (
    (
      SELECT 
       ARRAY_AGG(STRUCT(
         REGEXP_EXTRACT(y, '[^"]+') AS key
       , REGEXP_EXTRACT(y, ':([0-9]+)') AS value
       ))
      FROM UNNEST((
        SELECT REGEXP_EXTRACT_ALL(json,'"[smlx][meaxl]'||r'[^:]+:\"?[^"]+?') arr
        FROM (SELECT TO_JSON_STRING(x) json))) y
    )
    );
    
    SELECT location, unpivotted.*
    FROM `robotic-charmer-726.bl_test_data.reconfiguring_a_table` x
      , UNNEST(unpivot(x)) unpivotted
    
    

    上一个答案:

    使用表的 UNION(在 BigQuery 中使用“,”),以及一些列别名:

    SELECT Location, Size, Quantity
    FROM (
      SELECT Location, 'Small' as Size, Small as Quantity FROM [table]
    ), (
      SELECT Location, 'Medium' as Size, Medium as Quantity FROM [table]
    ), (
      SELECT Location, 'Large' as Size, Large as Quantity FROM [table]
    )
    

    【讨论】:

    • 感谢@FelipeHoffa 的快速而有帮助的回复!它不需要第二个和第三个'FROM'。所以最后它是这样工作的:'SELECT Location, Size, Quantity FROM (SELECT Location, 'Small' as Size, Small as Quantity FROM [table]), (SELECT Location, 'Medium' as Size, Medium as Quantity FROM [table] ), ( SELECT Location, 'Large' as Size, Large as Quantity FROM [table] )' 谢谢!
    • 对!查询已修复(如果您将示例数据上传到 BQ,那么我可以在将查询粘贴到此处之前对其进行测试)
    • 很高兴知道!如何将您指向我的 BigQuery 数据集? (我目前只使用 Tableau 和 BigQuery Web UI 查询内容,所以我不知道如何向某人指示我的数据集。谢谢
    • 如果你公开了一个数据集,那么 StackOverflow 上的任何人都可以查看它并提供帮助:)。例如,这是我 8 月份的维基百科综合浏览量日志:bigquery.cloud.google.com/table/… (project:dataset.table)
    • 感谢 2020 年更新祝贺。只是为了警告这行得通,只要列没有嵌套在结构本身内。他们的关键价值开始做有线的事情。它的实施仍然是一个很大的灵感来源。再次感谢。
    【解决方案2】:

    2021 年更新:

    BigQuery 中引入了新的 UNPIVOT 运算符。

    在使用 UNPIVOT 将 Q1、Q2、Q3、Q4 旋转到销售额和季度列之前:

    product Q1 Q2 Q3 Q4
    Kale 51 23 45 3
    Apple 77 0 25 2

    使用 UNPIVOT 将 Q1、Q2、Q3、Q4 旋转到销售和季度列之后:

    product sales quarter
    Kale 51 Q1
    Kale 23 Q2
    Kale 45 Q3
    Kale 3 Q4
    Apple 77 Q1
    Apple 0 Q2
    Apple 25 Q3
    Apple 2 Q4

    查询:

    WITH Produce AS (
      SELECT 'Kale' as product, 51 as Q1, 23 as Q2, 45 as Q3, 3 as Q4 UNION ALL
      SELECT 'Apple', 77, 0, 25, 2
    )
    SELECT * FROM Produce
    UNPIVOT(sales FOR quarter IN (Q1, Q2, Q3, Q4))
    

    【讨论】:

    • 为什么这被否决了?我可以这样解决我的问题。
    • 现在应该是公认的答案
    【解决方案3】:

    @Felipe,我使用标准 SQL 进行了尝试,但在查询的第一行出现错误:“列名位置在 [1:8] 时不明确”

    我使用了一个适合我的替代查询:

    SELECT Location, 'Small' as Size, Small as Quantity FROM `table`
    UNION ALL
    SELECT Location, 'Medium' as Size, Medium as Quantity FROM `table`
    UNION ALL
    SELECT Location, 'Large' as Size, Large as Quantity FROM `table`
    

    【讨论】:

      【解决方案4】:

      我有一个使用STRUCTs、ARRAYs 和CROSS JOIN + UNNEST 的解决方案:

      WITH
        My_Table_Metrics_Data AS (
        SELECT
          ...,
          [
              STRUCT('...' AS Metric, ... AS Data),
              STRUCT('...' AS Metric, ... AS Data),
          ] AS Metrics_Data
        FROM
          `My_Dataset.My_Table`
        WHERE
          ...
        )
      SELECT
        ...,
        Metric_Data
      FROM
        My_Table_Metrics_Data
      CROSS JOIN
        UNNEST(My_Table_Metrics_Data.Metrics_Data) AS Metric_Data
      

      完整说明及说明:https://yuhuisdatascienceblog.blogspot.com/2018/06/how-to-unpivot-table-in-bigquery.html

      【讨论】:

        猜你喜欢
        • 2021-11-08
        • 2014-12-04
        • 1970-01-01
        • 2014-10-26
        • 1970-01-01
        • 1970-01-01
        • 2023-04-02
        • 2021-11-19
        相关资源
        最近更新 更多