说我有一个包含以下信息的BQ表
| id | test.name | test.score |
|---- |----------- |------------ |
| 1 | a | 5 |
| | b | 7 |
| 2 | a | 8 |
| | c | 3 |
嵌套测试的位置。我如何将测试转换为下表?
| id | a | b | c |
|---- |--- |--- |--- |
| 1 | 5 | 7 | |
| 2 | 8 | | 3 |
我无法直接进行数据透视测试,因为在pivot(test)
处收到以下错误消息:Table-valued function not found
。先前的问题(1,2)不处理嵌套列或已过时。
以下查询看起来是一个有用的第一步:
select a.id, t
from `table` as a,
unnest(test) as t
但是,这只是为我提供了:
| id | test.name | test.score |
|---- |----------- |------------ |
| 1 | a | 5 |
| 1 | b | 7 |
| 2 | a | 8 |
| 2 | c | 3 |
答案 0 :(得分:1)
一个选项可能是使用条件聚合
select id,
max(case when test.name='a' then test.score end) as a,
max(case when test.name='b' then test.score end) as b,
max(case when test.name='c' then test.score end) as c
from
(
select a.id, t
from `table` as a,
unnest(test) as t
)A group by id
答案 1 :(得分:0)
有条件的聚合是一个好方法。如果您的桌子很大,您可能会发现它的性能最佳:
select t.id,
(select max(tt.score) from unnest(t.score) tt where tt.name = 'a') as a,
(select max(tt.score) from unnest(t.score) tt where tt.name = 'b') as b,
(select max(tt.score) from unnest(t.score) tt where tt.name = 'c') as c
from `table` t;
我之所以建议这样做是因为它避免了外部聚集。 unnest()
的出现没有对数据进行重新排列-我发现这在性能方面是一个巨大的胜利。
答案 2 :(得分:0)
以下是处理案件的通用/动态方式
EXECUTE IMMEDIATE (
SELECT """
SELECT id, """ ||
STRING_AGG("""MAX(IF(name = '""" || name || """', score, NULL)) AS """ || name, ', ')
|| """
FROM `project.dataset.table` t, t.test
GROUP BY id
"""
FROM (
SELECT DISTINCT name
FROM `project.dataset.table` t, t.test
ORDER BY name
)
);
如果要应用于您的问题的样本数据-输出为
Row id a b c
1 1 5 7 null
2 2 8 null 3