Reputation: 8903
The following query returns a list of key/value pairs:
SELECT ["name:apple", "color:red"] as fruit;
Is there a way to transpose the data so the results would be:
Update
I'm looking for a generalized solution, where the key and value and the array length of the results are unknown i.e: SELECT ["key0:val0", "key1:val1"...] as data;
Upvotes: 0
Views: 1886
Reputation: 7277
This should be a quick way to achieve your results:
#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
Upvotes: 2
Reputation: 4746
I guess the BigQuery way would be using sub-selects on the array:
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
Upvotes: 1
Reputation: 1946
Not sure if there's a more succinct way to do this but this works
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
Upvotes: 0