SQL - BigQuery - 在多个列中使用 Group 和 MAX - 类似于数据透视 table
SQL - BigQuery - Using Group & MAX in several columns - Similar to a pivot table
您将如何通过 SQL 解决这个问题?让我们举个例子
| id | type | score_a | score_b | score_c | label_a | label_b | label_c |
|----|------|---------|---------|---------|---------|---------|---------|
| 1 | A | 0.9 | | | L1 | | |
| 1 | B | | 0.7 | | | L2 | |
| 1 | B | | 0.2 | | | L3 | |
| 1 | C | | | 0.2 | | | L4 |
| 1 | C | | | 0.18 | | | L5 |
| 1 | C | | | 0.12 | | | L6 |
| 2 | A | 0.6 | | | L1 | | |
| 2 | A | 0.3 | | | L2 | | |
我想 return 每个 type
的最大分数与 label_X
结合使用,几乎就像一个枢轴 table 但具有这些自定义列名称。所以上面的结果将是这样的:
| id | type | score_a | label_a | score_b | label_b | score_c | label_c |
|----|------|---------|---------|---------|---------|---------|---------|
| 1 | A | 0.9 | L1 | 0.7 | L2 | 0.2 | L4 |
| 2 | A | 0.6 | L1 | NULL | NULL | NULL | NULL |
这样的事情是错误的,因为它会根据 type
和 label
产生两个结果
SELECT id,
MAX(score_a) as score_a,
label_a,
MAX(score_b) as score_b,
label_b as label_b,
MAX(score_c) as score_c,
label_c
FROM sample_table
GROUP BY id, label_a, label_b, label_c
有没有一种简单的方法可以通过 SQL 执行此操作,我现在正在从 BigQuery 进行此操作,并尝试按照 here 所述进行数据透视 table,但仍然没有成功如何将它们拼合成具有多列的一大行
还有其他想法吗?
更新
扩展 提到的关于设计的内容;此数据的来源是具有以下形式的 table:
| id | type | label | score |
|----|------|-------|-------|
| 1 | A | L1 | 0.9 |
| 1 | B | L2 | 0.7 |
| 1 | B | L3 | 0.2 |
| 1 | C | L4 | 0.6 |
| 1 | C | L5 | 0.2 |
使用类似
的查询将其转换为此问题顶部所描述的扁平状态
SELECT id,
type,
MAX(CASE WHEN type = 'A' THEN score ELSE 0 END) as score_a,
MAX(CASE WHEN type = 'B' THEN score ELSE 0 END) as score_b,
MAX(CASE WHEN type = 'C' THEN score ELSE 0 END) as score_c,
MAX(CASE WHEN model_type = 'theme' THEN label_score ELSE 0 END) as
-- labels
(CASE WHEN type = 'A' THEN label ELSE '' END) as label_a,
(CASE WHEN type = 'B' THEN label ELSE '' END) as label_b,
(CASE WHEN type = 'C' THEN label ELSE '' END) as label_c,
FROM table
GROUP id, label_a, label_b, label_c
您认为中间步骤对于获得最终解决方案是不必要的吗?
您可以进行条件聚合。在 Big Query 中,数组可以派上用场:
select
id,
max(score_a) score_a,
array_agg(label_a order by score_a desc limit 1)[offset(0)] label_a,
max(score_b) score_b,
array_agg(label_b order by score_b desc limit 1)[offset(0)] label_b,
max(score_c) score_c,
array_agg(label_c order by score_c desc limit 1)[offset(0)] label_c
from mytable
group by id
注意:在设计上,您不应该有多个列来存储每个类型的分数和标签;您已经有一个表示类型的列,因此您应该只有两列用于商店和类型。
您将如何通过 SQL 解决这个问题?让我们举个例子
| id | type | score_a | score_b | score_c | label_a | label_b | label_c |
|----|------|---------|---------|---------|---------|---------|---------|
| 1 | A | 0.9 | | | L1 | | |
| 1 | B | | 0.7 | | | L2 | |
| 1 | B | | 0.2 | | | L3 | |
| 1 | C | | | 0.2 | | | L4 |
| 1 | C | | | 0.18 | | | L5 |
| 1 | C | | | 0.12 | | | L6 |
| 2 | A | 0.6 | | | L1 | | |
| 2 | A | 0.3 | | | L2 | | |
我想 return 每个 type
的最大分数与 label_X
结合使用,几乎就像一个枢轴 table 但具有这些自定义列名称。所以上面的结果将是这样的:
| id | type | score_a | label_a | score_b | label_b | score_c | label_c |
|----|------|---------|---------|---------|---------|---------|---------|
| 1 | A | 0.9 | L1 | 0.7 | L2 | 0.2 | L4 |
| 2 | A | 0.6 | L1 | NULL | NULL | NULL | NULL |
这样的事情是错误的,因为它会根据 type
和 label
SELECT id,
MAX(score_a) as score_a,
label_a,
MAX(score_b) as score_b,
label_b as label_b,
MAX(score_c) as score_c,
label_c
FROM sample_table
GROUP BY id, label_a, label_b, label_c
有没有一种简单的方法可以通过 SQL 执行此操作,我现在正在从 BigQuery 进行此操作,并尝试按照 here 所述进行数据透视 table,但仍然没有成功如何将它们拼合成具有多列的一大行
还有其他想法吗?
更新
扩展
| id | type | label | score |
|----|------|-------|-------|
| 1 | A | L1 | 0.9 |
| 1 | B | L2 | 0.7 |
| 1 | B | L3 | 0.2 |
| 1 | C | L4 | 0.6 |
| 1 | C | L5 | 0.2 |
使用类似
的查询将其转换为此问题顶部所描述的扁平状态 SELECT id,
type,
MAX(CASE WHEN type = 'A' THEN score ELSE 0 END) as score_a,
MAX(CASE WHEN type = 'B' THEN score ELSE 0 END) as score_b,
MAX(CASE WHEN type = 'C' THEN score ELSE 0 END) as score_c,
MAX(CASE WHEN model_type = 'theme' THEN label_score ELSE 0 END) as
-- labels
(CASE WHEN type = 'A' THEN label ELSE '' END) as label_a,
(CASE WHEN type = 'B' THEN label ELSE '' END) as label_b,
(CASE WHEN type = 'C' THEN label ELSE '' END) as label_c,
FROM table
GROUP id, label_a, label_b, label_c
您认为中间步骤对于获得最终解决方案是不必要的吗?
您可以进行条件聚合。在 Big Query 中,数组可以派上用场:
select
id,
max(score_a) score_a,
array_agg(label_a order by score_a desc limit 1)[offset(0)] label_a,
max(score_b) score_b,
array_agg(label_b order by score_b desc limit 1)[offset(0)] label_b,
max(score_c) score_c,
array_agg(label_c order by score_c desc limit 1)[offset(0)] label_c
from mytable
group by id
注意:在设计上,您不应该有多个列来存储每个类型的分数和标签;您已经有一个表示类型的列,因此您应该只有两列用于商店和类型。