BQ数组查找:类似于NTH,但基于索引,而不是位置

问题描述 投票:1回答:2

NTH函数对于在BQ中提取嵌套数组元素非常有用,但它对给定表的实用程序取决于每行包含相同数量元素的嵌套数组,并且顺序相同。如果我有一个2+列嵌套数组,其中一列是变量名称/ ID,并且不同行中数组的不同实例具有不一致的命名和/或排序,是否有一种优雅的方法来获取/转动基于该变量的变量变量名称/ ID?

例如,如果row1具有customDimensions数组: index value 4 aaa 23 bbb 70 ccc

和row2有customDimensions数组: index value 4 ddd 70 eee

我想要运行类似的东西

SELECT 
NTHLOOKUP(70, customdims.index, customdims.value) as val70,
NTHLOOKUP(4, customdims.index, customdims.value) as val4,
NTHLOOKUP(23, customdims.index, customdims.value) as val23
from my_table;

得到: val70 val4 val23 ccc aaa bbb eee ddd (null)

通过为每个所需的索引值创建一个子查询,取消每个索引值中的数组并过滤WHERE index = (value),我已经能够获得这种结果,但随着变量堆积,这变得非常难看。还有其他选择吗?

编辑:基于米哈伊尔的答案(谢谢!!)我能够更优雅地编写我的查询。不像NTHLOOKUP那样光滑,但我会接受它:

select id,
max(case when index = 41 then value[OFFSET(0)] else '' end) as val41,
max(case when index = 59 then value[OFFSET(0)] else '' end) as val59
from
(select
        concat(array1.thing1, array1.thing2) as id,
        cd.index,
        ARRAY_AGG(distinct cd.value) as value
        FROM my_table g
        ,unnest(array1) as array1
        ,unnest(array1.customDimensions) as cd
        where index in (41,59)
        group by 1,2
        order by 1,2
) x
group by 1
order by 1
multidimensional-array nested google-bigquery
2个回答
1
投票

我能“提供”的最好的是(BigQuery Standard SQL)

#standardSQL
WITH `project.dataset.my_table` AS (
  SELECT ARRAY<STRUCT<index INT64, value STRING>>
    [(4, 'aaa'), (23, 'bbb'), (70, 'ccc')] customDimensions 
  UNION ALL
  SELECT ARRAY<STRUCT<index INT64, value STRING>>
    [(4, 'ddd'), (70, 'eee')] customDimensions 
)
SELECT cd.index, ARRAY_AGG(cd.value) VALUES
FROM `project.dataset.my_table`,
UNNEST(customDimensions) cd
GROUP BY cd.index   

结果如下

Row index   values   
1   4       aaa  
            ddd  
2   23      bbb  
3   70      ccc  
            eee   

我建议保留这个扁平版本,因为它可以满足我能想到的大多数实际情况

但是如果你还想进一步调整这一点 - 在BigQuery中有很多关于如何使用pivot的帖子


1
投票

通过为每个所需的索引值创建一个子查询,取消每个索引值中的数组并过滤WHERE index = (value),我已经能够获得这种结果,但随着变量堆积,这变得非常难看。还有其他选择吗?

是的,您可以使用用户定义的函数来封装公共逻辑。例如,

CREATE TEMP FUNCTION NTHLOOKUP(
  targetIndex INT64,
  customDimensions ARRAY<STRUCT<index INT64, value STRING>>
) AS (
  (SELECT value FROM UNNEST(customDimensions)
   WHERE index = targetIndex)
);

SELECT 
  NTHLOOKUP(70, customDimensions) as val70,
  NTHLOOKUP(4, customDimensions) as val4,
  NTHLOOKUP(23, customDimensions) as val23
from my_table;
© www.soinside.com 2019 - 2024. All rights reserved.