Big Query SQL 连接或链接管道字符串或字符串数​​组中的值

Big Query SQL concatenating or linking values in piped strings or arrays of strings

我在一个大 BQ 中有两个字段 table。这两个字段都是字符串。两个字符串都被格式化为表示由竖线分隔的几个值,每个字符串中的值数量相同。我需要将第一组中的每个值与第二组中的每个值相关联。例如:

id   names     nums

x    "a|b|c"   "3|9|5"
y    "d"       "1"
z    "e|f"     "4|7"

我需要得出这样的结果:

x,a,3
x,b,9
x,c,5
y,d,1
z,e,4
z,f,7

第二个输入字符串是一个数字序列,但我不介意它是数字还是字符串(我会弄清楚转换)。
似乎很明显我需要在某些时候使用 split() 可以将字符串转换为数组,但是我怎样才能从左到右而不是按长度连接数组?
我知道我只能在索引相等的情况下使用带有索引和 select 的双重 unnest,但是我不想使用这种方法,因为它使已经很大的输入 table 变得巨大(在 select使用相等的索引)。
感谢您的任何想法!

下面是一个生成一系列下标并使用数组提取值的方法:

select id, split(names, '|')[safe_ordinal(n)] as names, 
       split(nums, '|')[safe_ordinal(n)] as nums
from (select 'x' as id, 'a|b|c' as names, '3|9|5' as nums union all
      select 'y', 'd', '1' union all
      select 'z', 'e|f', '4|7'
     ) t cross join
     unnest(generate_array(1, array_length(split(names, '|')))) as n;

这使用 names 的长度来确定有多少个值。

BigQuery 标准的替代选项 SQL

#standardSQL
SELECT id, name, num
FROM `project.dataset.table`,
UNNEST(SPLIT(names, '|')) name WITH OFFSET
JOIN UNNEST(SPLIT(nums, '|')) num WITH OFFSET
USING(OFFSET)

如果适用于您问题中的示例数据,如下例所示

#standardSQL
WITH `project.dataset.table` AS (
  SELECT 'x' id, 'a|b|c' names, '3|9|5' nums UNION ALL
  SELECT 'y', 'd', '1' UNION ALL
  SELECT 'z', 'e|f', '4|7' 
)
SELECT id, name, num
FROM `project.dataset.table`,
UNNEST(SPLIT(names, '|')) name WITH OFFSET
JOIN UNNEST(SPLIT(nums, '|')) num WITH OFFSET
USING(OFFSET)

结果是

Row id  name    num  
1   x   a       3    
2   x   b       9    
3   x   c       5    
4   y   d       1    
5   z   e       4    
6   z   f       7    

以上内容可以重构为使用 UDF,因此主查询变得简单易读 - 如以下示例所示

#standardSQL
CREATE TEMP FUNCTION xxx(arr1 ANY TYPE, arr2 ANY TYPE) 
RETURNS ARRAY<STRUCT<name STRING, num STRING>> AS (
ARRAY(
  SELECT AS STRUCT el1, el2
  FROM UNNEST(SPLIT(arr1, '|')) el1 WITH OFFSET
  JOIN UNNEST(SPLIT(arr2, '|')) el2 WITH OFFSET
  USING(OFFSET)
));
SELECT id, x.*
FROM `project.dataset.table`, UNNEST(xxx(names, nums)) x

显然具有相同的输出