Поиск в массиве BQ: аналогично NTH, но основан на индексе, а не на позиции - PullRequest
0 голосов
/ 24 апреля 2018

Функция NTH действительно полезна для извлечения вложенных элементов массива в BQ, но ее полезность для данной таблицы зависит от вложенного массива каждой строки, содержащего одинаковое количество элементов и в том же порядке. Если у меня есть вложенный массив из столбцов 2+, где один столбец является именем / идентификатором переменной, а разные экземпляры массива в разных строках имеют непоследовательное именование и / или упорядочение, существует ли элегантный способ извлечения / поворота переменной на основе Имя переменной / 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

Ответы [ 2 ]

0 голосов
/ 24 апреля 2018

Лучшее, что я могу «предложить», ниже (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   

Я бы порекомендовал остаться с этой плоской версией, так какПодходит для большинства практических случаев, о которых я могу подумать

Но если вы все еще хотите развить это - есть много сообщений, связанных с тем, как pivot в BigQuery

0 голосов
/ 24 апреля 2018

Я смог получить такой результат, выполнив подзапрос для каждого желаемого значения индекса, развернув массив в каждом и отфильтровав 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;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...