【问题标题】:Big Query - Transpose Specific fields into Columns大查询 - 将特定字段转换为列
【发布时间】:2020-10-19 09:09:03
【问题描述】:

我们在 Big Query 中有一个如下表。

输入表:

 Name | Question  | Answer
 -----+-----------+-------
 Bob  | Interest  | a     
 Sue  | Interest  | a
 Sue  | Interest  | b
 Joe  | Interest  | b
 Joe  | Gender    | Male
 Bob  | Gender    | Female
 Sue  | DOB       | 2020-10-17

我们希望将上表转换为以下格式,使其对 BI/Visualisation 友好。

目标/所需表:

 +----------------------------------------+
 | Name | a | b | c | Gender | DOB        |
 +----------------------------------------+
 | Bob  | 1 | 0 | 0 | Female | 2020-10-17 |
 | Sue  | 1 | 1 | 0 |   -    |     -      |
 | Joe  | 0 | 1 | 0 |  Male  |     -      |
 +----------------------------------------+

【问题讨论】:

    标签: sql google-cloud-platform google-bigquery


    【解决方案1】:

    以下适用于 BigQuery 标准 SQL不依赖于了解具体问题,并且对于任何问题和答案的值都足够通用

    EXECUTE IMMEDIATE (
      SELECT """
        SELECT name, """ || STRING_AGG("""MAX(IF(answer = '""" || value || """', 1, 0)) AS """ || value, ', ')   
    FROM (
      SELECT DISTINCT answer value FROM `project.dataset.table`
      WHERE question = 'Interest' ORDER BY value
    )) || (
      SELECT ", " || STRING_AGG("""MAX(IF(question = '""" || value || """', answer, '-')) AS """ || value, ', ')   
    FROM (
        SELECT DISTINCT question value FROM `project.dataset.table`
        WHERE question != 'Interest' ORDER BY value
    )) || """  
      FROM `project.dataset.table` 
      GROUP BY name
      """;    
    

    【讨论】:

    • 抱歉,我看不出需求如此复杂,以至于您需要动态 sql 或多个 select distinct 语句
    • @Used_By_Already - 我完全不同意你的观点!想得更远,看得更远,那只是特定的例子!!!当你学会这样做的时候——来判断吧!或者最好只提供您的答案。但是投反对票的正确答案——仅仅因为你没有看到任何东西——是很低的!!我建议你重新阅读我的答案——尤其是第一句话——所以也许你会明白并改变主意并撤回你的反对意见
    • 虽然这对于 OP 显示的简单案例来说可能有点过头了,但这在技术上是正确的。
    • 让我们看看 OP 会说什么 - 从经验 - 通常虽然样本数据只包含几个要旋转的值 - 真实案例有 10 或 100 - 在这种情况下 - 我的答案中提出的解决方案是唯一的出路!所以我真的不明白为什么你会拒绝使用正确的方向,为什么你会把它定性为矫枉过正!在这种情况下,技巧还在于它是两个不同的支点——这使得它与 SO 上的所有/任何以前的支点相关问题完全不同——至少对于 google-bigquery 标签
    • @mikhail 由于我们在查询中有多个枢轴,在这种情况下如何将最终结果存储到表中?
    【解决方案2】:

    使用条件聚合:

    select name,
           countif(question = 'Interest' and answer = 'a') as a,
           countif(question = 'Interest' and answer = 'b') as b,
           countif(question = 'Interest' and answer = 'c') as c,
           max(case when question = 'gender' then answer end) as gender,
           max(case when question = 'DOB' then answer end) as dob
    from t
    group by name;
    

    注意:当缺少值时,这将返回 NULL。对我来说,这比 '-' 更有意义,尽管可以调整逻辑以返回连字符。

    【讨论】:

      【解决方案3】:

      使用coalesce() 将提供破折号,而没有动态sql 和多选的复杂性(和弱点)。请注意,这只是 Gordon Linoff 答案的变体 - 我只是添加了破折号而不是 NULL 的逻辑。

      select name,
             countif(question = 'Interest' and answer = 'a') as a,
             countif(question = 'Interest' and answer = 'b') as b,
             countif(question = 'Interest' and answer = 'c') as c,
             coalesce(max(case when question = 'gender' then answer end),'-') as gender,
             coalesce(max(case when question = 'DOB' then answer end),'-') as dob
      from t
      group by name;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-06-08
        • 2020-07-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多