我要转换此数据:
id value
---------
1 v1=10
1 v2=20
1 v3=30
2 v1=40
看起来像这样:
id v1 v2 v3
---------------------------
1 10 20 30
2 40 null null
有什么解决方案吗?我想解决它bigquery的标准sql。
答案 0 :(得分:1)
SELECT
id,
MAX(IF(name = 'v1', value, NULL)) AS v1,
MAX(IF(name = 'v2', value, NULL)) AS v2,
MAX(IF(name = 'v3', value, NULL)) AS v3
FROM (
SELECT
SPLIT(value, '=')[OFFSET(0)] AS name,
SPLIT(value, '=')[OFFSET(1)] AS value
FROM dataset.table
)
GROUP BY id
答案 1 :(得分:0)
以下几个选项-全部用于BigQuery Standrad SQL
选项1-硬编码枢轴
假设您预先知道要创建的列的编号和名称
在这种情况下,您需要做什么
#standardSQL
SELECT
id,
MAX(IF(key = 'v1', val, NULL)) v1,
MAX(IF(key = 'v2', val, NULL)) v2,
MAX(IF(key = 'v3', val, NULL)) v3
FROM `project.dataset.table`,
UNNEST([STRUCT<key STRING, val STRING>(SPLIT(value,"=")[OFFSET(0)], SPLIT(value, "=")[OFFSET(1)])])
GROUP BY id
您可以使用下面的问题中的虚拟数据进行测试,操作
#standardSQL
WITH `project.dataset.table` AS (
SELECT 1 id, 'v1=10' value UNION ALL
SELECT 1, 'v2=20' UNION ALL
SELECT 1, 'v3=30' UNION ALL
SELECT 2, 'v1=40'
)
SELECT
id,
MAX(IF(key = 'v1', val, NULL)) v1,
MAX(IF(key = 'v2', val, NULL)) v2,
MAX(IF(key = 'v3', val, NULL)) v3
FROM `project.dataset.table`,
UNNEST([STRUCT<key STRING, val STRING>(SPLIT(value,"=")[OFFSET(0)], SPLIT(value, "=")[OFFSET(1)])])
GROUP BY id
-- ORDER BY id
结果符合预期:
Row id v1 v2 v3
1 1 10 20 30
2 2 40 null null
选项2-动态旋转
如果您不知道列的数目和名称-您将需要首先生成类似于上述选项#1中的脚本
您应该在下面运行以获得它
#standardSQL
SELECT CONCAT('SELECT id, ',
STRING_AGG(
CONCAT('MAX(IF(key = "', key, '", val, NULL)) as ', key)
)
,' FROM `project.dataset.table`, UNNEST([STRUCT<key STRING, val STRING>(SPLIT(value, "=")[OFFSET(0)], SPLIT(value, "=")[OFFSET(1)])]) GROUP BY id')
FROM (
SELECT SPLIT(value, '=')[OFFSET(0)] key
FROM `project.dataset.table`
GROUP BY key
)
例如,如果您要对同一个虚拟人运行
#standardSQL
WITH `project.dataset.table` AS (
SELECT 1 id, 'v1=10' value UNION ALL
SELECT 1, 'v2=20' UNION ALL
SELECT 1, 'v3=30' UNION ALL
SELECT 2, 'v1=40'
)
SELECT CONCAT('SELECT id, ',
STRING_AGG(
CONCAT('MAX(IF(key = "', key, '", val, NULL)) as ', key)
)
,' FROM `project.dataset.table`, UNNEST([STRUCT<key STRING, val STRING>(SPLIT(value, "=")[OFFSET(0)], SPLIT(value, "=")[OFFSET(1)])]) GROUP BY id')
FROM (
SELECT SPLIT(value, '=')[OFFSET(0)] key
FROM `project.dataset.table`
GROUP BY key
)
您将获得以下字符串
SELECT id, MAX(IF(key = "v1", val, NULL)) AS v1,MAX(IF(key = "v2", val, NULL)) AS v2,MAX(IF(key = "v3", val, NULL)) AS v3 FROM `project.dataset.table`, UNNEST([STRUCT<key STRING, val STRING>(SPLIT(value, "=")[OFFSET(0)], SPLIT(value, "=")[OFFSET(1)])]) GROUP BY id
现在,如果您针对虚拟数据运行此脚本
#standardSQL
WITH `project.dataset.table` AS (
SELECT 1 id, 'v1=10' value UNION ALL
SELECT 1, 'v2=20' UNION ALL
SELECT 1, 'v3=30' UNION ALL
SELECT 2, 'v1=40'
)
SELECT id, MAX(IF(key = "v1", val, NULL)) AS v1,MAX(IF(key = "v2", val, NULL)) AS v2,MAX(IF(key = "v3", val, NULL)) AS v3 FROM `project.dataset.table`, UNNEST([STRUCT<key STRING, val STRING>(SPLIT(value, "=")[OFFSET(0)], SPLIT(value, "=")[OFFSET(1)])]) GROUP BY id
您将获得与选项1相同的结果-但不是-现在最终为您动态生成了最终查询
选项3-展平键-值与枢轴
透视很酷,但在许多实际情况下,发现以下简单方法非常有用,并且更适合处理
#standardSQL
WITH `project.dataset.table` AS (
SELECT 1 id, 'v1=10' value UNION ALL
SELECT 1, 'v2=20' UNION ALL
SELECT 1, 'v3=30' UNION ALL
SELECT 2, 'v1=40'
)
SELECT
id,
SPLIT(value,"=")[OFFSET(0)] key,
SPLIT(value, "=")[OFFSET(1)] val
FROM `project.dataset.table`
给出普通的香草键值扁平化结构
Row id key val
1 1 v1 10
2 1 v2 20
3 1 v3 30
4 2 v1 40