【问题标题】:SQL/Bigquery: Pivot combinations of rows into columns, keeping all pairsSQL/Bigquery:将行组合转换为列,保留所有对
【发布时间】:2021-08-04 18:11:43
【问题描述】:

假设我有一张这样的桌子:

| id |  brand |   fuel | mpg |
|:--:|:------:|:------:|:---:|
| 1  | ford   | diesel | 14  |
| 1  | ford   | gas    | 20  |
| 1  | toyota | diesel | 30  |
| 1  | toyota | gas    | 35  |

我希望旋转列,结果如下:

| id |  ford  | toyota | toyota_mpg | ford_mpg |
|:--:|:------:|--------|:----------:|:--------:|
| 1  | diesel | diesel | 30         | 14       |
| 1  | gas    | gas    | 35         | 20       |
| 1  | diesel | gas    | 35         | 14       |
| 1  | gas    | diesel | 30         | 20       |

到目前为止,我已经

SELECT id,
         MAX(CASE WHEN end_use = 'ford' THEN fuel ELSE NULL END) ford,
         SUM(CASE WHEN end_use = 'ford' THEN mpg ELSE NULL END) ford_mpg,

         MAX(CASE WHEN end_use = 'toyota' THEN fuel ELSE NULL END) toyota,
         SUM(CASE WHEN end_use = 'toyota' THEN mpg ELSE NULL END) toyota_mpg,
       FROM table GROUP BY id, fuel

结果如下,当燃料对齐时给我正确的结果:

| id |  ford  | toyota | toyota_mpg | ford_mpg |
|:--:|:------:|--------|:----------:|:--------:|
| 1  | diesel | diesel | 30         | 14       |
| 1  | gas    | gas    | 35         | 20       |

但我无法获得燃料组合(它们不匹配的地方)。

【问题讨论】:

    标签: sql google-bigquery pivot case


    【解决方案1】:

    试试下面

    select id, 
      t1.fuel ford, 
      t2.fuel toyota, 
      t1.mpg ford_mpg, 
      t2.mpg toyota_mpg
    from data t1
    join data t2
    using (id)
    where t1.brand < t2.brand           
    

    如果应用于您问题中的样本数据 - 输出是

    【讨论】:

      【解决方案2】:

      您可以从大查询中探索pivot operator。虽然我不确定您在 id 级别上找出 sum/avg/max/min 的用例!

      WITH
        result AS (
        SELECT
          1 AS id,
          'ford' AS brand,
          'diesel' AS fuel,
          14 AS mpg
        UNION ALL
        SELECT
          1 AS id,
          'ford' AS brand,
          'gas' AS fuel,
          20 AS mpg
        UNION ALL
        SELECT
          1 AS id,
          'toyota' AS brand,
          'diesel' AS fuel,
          30 AS mpg
        UNION ALL
        SELECT
          1 AS id,
          'toyota' AS brand,
          'gas' AS fuel,
          35 AS mpg ),
        pivot_result AS (
        SELECT
          id,
          ford,
          toyota,
          mpg_ford,
          mpg_toyota
        FROM (
          SELECT
            *
          FROM (
            SELECT
              id,
              fuel,
              brand brand_,
              brand,
              mpg
            FROM
              result ) PIVOT ( AVG(mpg) mpg FOR brand IN ('ford',
                'toyota')) ) PIVOT (MAX(fuel) FOR brand_ IN ('ford',
              'toyota')) )
      SELECT
        f.id,
        f.ford,
        t.toyota,
        t.mpg_toyota,
        f.mpg_ford
      FROM
        pivot_result f
      INNER JOIN (
        SELECT
          id,
          toyota,
          mpg_toyota
        FROM
          pivot_result) t
      ON
        t.id = f.id
      WHERE
        (f.ford IS NOT NULL
          AND f.mpg_ford IS NOT NULL
          AND t.toyota IS NOT NULL
          AND t.mpg_toyota IS NOT NULL)
      GROUP BY
        1,
        2,
        3,
        4,
        5
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-08-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-14
        • 1970-01-01
        相关资源
        最近更新 更多