将嵌套列添加到BigQuery表中,并连接标准SQL中另一个嵌套列的值
我有一个相当复杂的数据集,通过一个不容易调整的DAG被拉到BigQuery表中 此作业将数据拉入具有以下格式的表:将嵌套列添加到BigQuery表中,并连接标准SQL中另一个嵌套列的值,sql,join,nested,google-bigquery,bigquery-standard-sql,Sql,Join,Nested,Google Bigquery,Bigquery Standard Sql,我有一个相当复杂的数据集,通过一个不容易调整的DAG被拉到BigQuery表中 此作业将数据拉入具有以下格式的表: | Line_item_id | Device | |--------------|----------------| | 123 | 202; 5; 100 | | 124 | 100; 2 | | 135 | 504; 202; 2 | 目前,我正在BQ Web UI中使用标准S
| Line_item_id | Device |
|--------------|----------------|
| 123 | 202; 5; 100 |
| 124 | 100; 2 |
| 135 | 504; 202; 2 |
目前,我正在BQ Web UI中使用标准SQL编写的查询将设备ID拆分为单独的嵌套行:
SELECT
Line_item_id,
ARRAY(SELECT AS STRUCT(SPLIT(RTRIM(Device,';'),'; '))) as Device,
输出:
| Line_item_id | Device |
|--------------|--------|
| 123 | 202 |
| | 203 |
| | 504 |
| 124 | 102 |
| | 2 |
| 135 | 102 |
我面临的困难是,我有一个单独的匹配表,其中包含设备ID及其对应的名称。我需要将设备名称添加到上表中,作为相应ID旁边的嵌套值
匹配表的行数更多,如下所示:
| Device_id | Device_name |
|-----------|-------------|
| 202 | Smartphone |
| 203 | AppleTV |
| 504 | Laptop |
我想要的理想输出是:
| Line_item_id | Device_id | Device_name |
|--------------|-----------|-------------|
| 123 | 202 | Android |
| | 203 | AppleTV |
| | 504 | Laptop |
| 124 | 102 | iphone |
| | 2 | Unknown |
| 135 | 102 | iphone |
如果有人知道如何做到这一点,我将不胜感激
编辑:
Gordon的解决方案工作得很好,但除此之外,如果有人想在以后重新嵌套数据,以便最终得到相同的表和其他嵌套行,我最终得到的查询是:
select t.line_item_id, ARRAY_AGG(STRUCT(d as id, ot.name as name)) as device
from first_table t cross join
unnest(split(Device, '; ')) d join
match_table ot
on ot.id = d
GROUP BY line_item_id
您可以将解析逻辑移动到from子句,然后加入所需的内容:
select *
from (select 124 as line_item_id, '203; 100; 6; 2' as device) t cross join
unnest(split(device, '; ')) d join
other_table ot
on ot.device = d;
您可以将解析逻辑移动到from子句,然后加入所需的内容:
select *
from (select 124 as line_item_id, '203; 100; 6; 2' as device) t cross join
unnest(split(device, '; ')) d join
other_table ot
on ot.device = d;
您需要的是取消对设备数组内容的测试,然后在加入设备元表后将其回滚:
select
line_item_id,
array_agg(struct(device_id as device_id, device_name as device_name)) as devices
from (
select
d.line_item_id,
device_id,
n.device_name
from `mydataset.basetable` d, unnest(d.device_ids) as device_id
left join `mydataset.devices_table` n on n.device_id = device_id
)
group by line_item_id
希望这有帮助。您需要的是取消对设备数组内容的测试,然后在加入设备元表后将其回滚:
select
line_item_id,
array_agg(struct(device_id as device_id, device_name as device_name)) as devices
from (
select
d.line_item_id,
device_id,
n.device_name
from `mydataset.basetable` d, unnest(d.device_ids) as device_id
left join `mydataset.devices_table` n on n.device_id = device_id
)
group by line_item_id
希望这能有所帮助。下面是针对BigQuery标准SQL的。不需要分组依据
#standardSQL
SELECT * EXCEPT(Device),
ARRAY(
SELECT AS STRUCT Device_id AS id, Device_name AS name
FROM UNNEST(SPLIT(REPLACE(Device, ' ', ''), ';')) Device_id WITH OFFSET
JOIN `project.dataset.devices`
USING(Device_id)
ORDER BY OFFSET
) Device
FROM `project.dataset.items`
如果要应用于您问题中的样本数据-结果为
仅供参考:我使用以下数据进行测试
WITH `project.dataset.items` AS (
SELECT 123 Line_item_id, '202; 5; 100' Device UNION ALL
SELECT 124, '100; 2' UNION ALL
SELECT 135, '504; 202; 2'
), `project.dataset.devices` AS (
SELECT '202' Device_id, 'Smartphone' Device_name UNION ALL
SELECT '203', 'AppleTV' UNION ALL
SELECT '504', 'Laptop' UNION ALL
SELECT '5', 'abc' UNION ALL
SELECT '100', 'xyz' UNION ALL
SELECT '2', 'zzz'
)
下面是BigQuery标准SQL。不需要分组依据
#standardSQL
SELECT * EXCEPT(Device),
ARRAY(
SELECT AS STRUCT Device_id AS id, Device_name AS name
FROM UNNEST(SPLIT(REPLACE(Device, ' ', ''), ';')) Device_id WITH OFFSET
JOIN `project.dataset.devices`
USING(Device_id)
ORDER BY OFFSET
) Device
FROM `project.dataset.items`
如果要应用于您问题中的样本数据-结果为
仅供参考:我使用以下数据进行测试
WITH `project.dataset.items` AS (
SELECT 123 Line_item_id, '202; 5; 100' Device UNION ALL
SELECT 124, '100; 2' UNION ALL
SELECT 135, '504; 202; 2'
), `project.dataset.devices` AS (
SELECT '202' Device_id, 'Smartphone' Device_name UNION ALL
SELECT '203', 'AppleTV' UNION ALL
SELECT '504', 'Laptop' UNION ALL
SELECT '5', 'abc' UNION ALL
SELECT '100', 'xyz' UNION ALL
SELECT '2', 'zzz'
)
. . 我不清楚203和6在124中的位置。我不清楚203和6在124中的位置。嗨,戈登,如果这两个表都有名字,你能调整一下吗?您使用的from子句中的select语句对我不起作用,因为我也从查询中的表中提取原始行\项\ id和设备信息,而不是从中写入scratch@DarceyBM . . . 只要用您正在使用的表替换t之前的子查询即可。谢谢!为了简单起见,这里没有包括更多的列,但这很容易调整。嗨,Gordon,如果两个表都有名称,你能调整一下吗?您使用的from子句中的select语句对我不起作用,因为我也从查询中的表中提取原始行\项\ id和设备信息,而不是从中写入scratch@DarceyBM . . . 只要用您正在使用的表替换t之前的子查询即可。谢谢!为了简单起见,这里没有包括更多的专栏,但这很容易调整。