我有一个相当复杂的数据集,通过无法轻松调整的Airflow DAG导入到BigQuery表中。
此作业将数据提取到具有以下格式的表中:
| 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 |
如果有人知道如何实现这一目标,我将不胜感激。
编辑:
戈登的解决方案可以完美地工作,但是除此之外,如果有人想在以后重新嵌套数据(因此您实际上会得到相同的表和其他嵌套行),这就是我最终得到的查询:
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
答案 0 :(得分:1)
您可以将解析逻辑移至from
子句,然后移至所需的join
处:
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;
答案 1 :(得分:0)
您需要的是[a-zA-Z]
设备数组的内容,然后在与UNNEST
元表结合后将其回滚:
devices
希望这会有所帮助。
答案 2 :(得分:0)
以下是BigQuery标准SQL的内容。不需要GROUP BY ...
#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'
)