Bigquery-将数组转置为列

时间:2018-11-22 09:09:24

标签: arrays google-bigquery transpose

以下查询返回键/值对的列表:

SELECT ["name:apple", "color:red"] as fruit;

结果:
enter image description here

是否有一种方法可以转置数据,所以结果将是:
enter image description here

更新 我正在寻找一种通用的解决方案,其中键和值以及结果的数组长度是未知的,即:SELECT ["key0:val0", "key1:val1"...] as data;

3 个答案:

答案 0 :(得分:2)

这应该是实现结果的快速方法:

#standardSQL
with items as (
  select ["name:apple", "color:red"] p union all
  select ["name:orange", "color:orange"] UNION ALL
  select ["name:grapes", "color:green"]
),
arrayed as (
  select 
    array_agg(
       struct(
        if(split(p, ":")[offset(0)] = 'name', split(p, ":")[offset(1)], '') as name, 
        if(split(p, ":")[offset(0)] = 'color', split(p, ":")[offset(1)], '') as color 
      )
    ) item  from items, unnest(p) p
)
select 
  array((select i.name from unnest(item) i where i.name != '')) as name,
  array((select i.color from unnest(item) i where i.color != '')) as color
from arrayed

答案 1 :(得分:1)

我猜想BigQuery的方式是在数组上使用子选择:

WITH t AS (SELECT * FROM UNNEST([ 
    struct(['name:apple','color:red'] AS fruit), 
    struct(['name:pear','color:purple'] AS fruit)
  ]) )

SELECT
  (SELECT SPLIT(f, ':')[SAFE_OFFSET(1)] FROM t.fruit f WHERE SPLIT(f, ':')[SAFE_OFFSET(0)]='name') AS name,
  (SELECT SPLIT(f, ':')[SAFE_OFFSET(1)] FROM t.fruit f WHERE SPLIT(f, ':')[SAFE_OFFSET(0)]='color') AS color
FROM t

答案 2 :(得分:0)

不确定是否有更简洁的方法来做到这一点,但这行得通

WITH CTE AS (
SELECT ["name:apple", "color:red"] as fruit
UNION ALL
SELECT ["name:pear", "color:green"]
),

CTE2 AS (
SELECT row_number() over () as rowNumber, fruit
FROM CTE
)

SELECT max(if(REGEXP_CONTAINS(fruit,'name:'),replace(fruit,'name:',''),null)) name,
  max(if(REGEXP_CONTAINS(fruit,'color:'),replace(fruit,'color:',''),null)) color
FROM CTE2,
UNNEST(fruit) as fruit
GROUP BY rowNumber