Разверните несколько массивов в Bigquery и снова соберите - PullRequest
0 голосов
/ 02 мая 2020

Я пытаюсь раскрутить несколько вложенных массивов в Bigquery, отфильтровать их и собрать новые массивы вместе. Моя проблема в том, что я получаю дублированные значения.

Пример данных:

Example of nested rows

В образе есть два примера строк данных с массивом «vendor», который содержит два массива «topi c» и «category»

Я хочу отфильтровать по vendor.topi c .score> = 0.8, vendor.categories.score> = 0.8, а также избавьтесь от столбца vendor.topi c .position.

Результат должен выглядеть следующим образом:

Result example

Сначала я попытался решить эту проблему с несколькими гнездами для каждого массива, но это дает мне дублированные значения во вновь созданных массивах:

SELECT
  id,
  ARRAY_AGG(STRUCT(vendor_topics.label AS topics_label,
      vendor_topics.score AS topics_score)),
  ARRAY_AGG(STRUCT(vendor_categories.label AS category_label,
      vendor_categories.score AS category_score))
FROM
  `source_table`,
  UNNEST(vendor.topics) vendor_topics,
  UNNEST(vendor.categories) vendor_categories
WHERE
  AND vendor_categories.score >= 0.8
  AND vendor_topics.score >= 0.8
GROUP BY
  1
LIMIT
  10

Далее я попытался использовать подзапросы, которые заканчивались словами «Превышено ограничение API: невозможно вернуть строку, превышающую пределы API. Чтобы получить строку, экспортируйте таблицу.»

SELECT
  id,
  (
  SELECT
    ARRAY_AGG(STRUCT(vendor_topics.label AS topics_label,
        vendor_topics.score AS topics_score))
  FROM
    `source_table` articles,
    UNNEST(vendor.topics) vendor_topics
    WHERE
  vendor_topics.score >= 0.8),

    (
  SELECT
    ARRAY_AGG(STRUCT(vendor_categories.label AS category_label,
      vendor_categories.score AS category_score))
  FROM
    `source_table`,
    UNNEST(vendor.categories) vendor_categories
    WHERE
  vendor_categories.score >= 0.8)
FROM
  `source_table`
GROUP BY
  1

Сейчас У меня нет идей, и я надеюсь, что кто-нибудь поможет мне решить эту проблему, пожалуйста.

1 Ответ

2 голосов
/ 02 мая 2020

Я создаю ваши образцы данных также двумя способами, так как не уверен, является ли поставщик массивом или нет. От чего у вас могут возникнуть осложнения.

Первым примером поставщика является массив

#standardSQL
WITH `yourTable` AS (
  select 111 as id, (select 
          array(select 
                   struct(array(select struct('A' as label, 0.1 as score,2 as position) 
                         union all select struct('B' as label, 0.9 as score,5 as position)
                         union all select struct('C' as label, 0.9 as score,8 as position)
                              ) as topic,
                              array(select struct('Cat1' as label, 0.8 as score) 
                         union all select struct('Cat2' as label, 0.3 as score)
                              ) as categories 
                          )
                  )) as vendor
    union all 
    select 222 as id, (select 
          array(select 
                   struct(array(select struct('X' as label, 0.3 as score,2 as position) 
                         union all select struct('Y' as label, 0.9 as score,3 as position)
                              ) as topic,
                              array(select struct('Cat33' as label, 0.9 as score) 
                         union all select struct('Cat99' as label, 0.4 as score)
                         union all select struct('Cat44' as label, 0.85 as score)
                              ) as categories 
                          )
                  )) as vendor
)
 ------
  SELECT id,array(
  select struct(
              (select array_agg(t) as topic from unnest(vendor),unnest(topic) t where t.score>=0.8) as topic,
              (select array_agg(t) as categories from unnest(vendor),unnest(categories) t where t.score>=0.8) as categories
            )
   ) as vendor2   from yourTable

Возвращает:

enter image description here

В основном, как вам нужно прочитать это: - вы выбираете строку с id и vendor2 - по природе vendor2 является массивом (пропустите это для второго примера) - тогда вам нужны два ключа как struct topic и categories - topic или categories являются массивом структур.

2-й пример (где vendor не является массивом):

#standardSQL
WITH `yourTable` AS (
  select 111 as id, (select 
                   struct(array(select struct('A' as label, 0.1 as score,2 as position) 
                         union all select struct('B' as label, 0.9 as score,5 as position)
                         union all select struct('C' as label, 0.9 as score,8 as position)
                              ) as topic,
                              array(select struct('Cat1' as label, 0.8 as score) 
                         union all select struct('Cat2' as label, 0.3 as score)
                              ) as categories 
                          )
                  ) as vendor
    union all 
    select 222 as id, (select 
                   struct(array(select struct('X' as label, 0.3 as score,2 as position) 
                         union all select struct('Y' as label, 0.9 as score,3 as position)
                              ) as topic,
                              array(select struct('Cat33' as label, 0.9 as score) 
                         union all select struct('Cat99' as label, 0.4 as score)
                         union all select struct('Cat44' as label, 0.85 as score)
                              ) as categories 
                          )
                  ) as vendor
)


 SELECT id,struct(
              (select array_agg(t) as topic from unnest(vendor.topic) t where t.score>=0.8) as topic,
              (select array_agg(t) as categories from unnest(vendor.categories) t where t.score>=0.8) as categories
   ) as vendor2   from yourTable
...