BigQuery агрегирует в массив на основе id и id_type - PullRequest
0 голосов
/ 25 января 2019

У меня есть таблица, которая выглядит примерно так:

WITH
  table AS (
  SELECT 1 object_id, 234 type_id, 2 type_level UNION ALL
  SELECT 1, 23, 1 UNION ALL
  SELECT 1, 24, 1 UNION ALL
  SELECT 1, 2, 0 UNION ALL
  SELECT 1, 2, 0 UNION ALL
  SELECT 2, 34, 1 UNION ALL
  SELECT 2, 46, 1 UNION ALL
  SELECT 2, 465, 2 UNION ALL
  SELECT 2, 349, 2 UNION ALL
  SELECT 2, 4, 0 UNION ALL
  SELECT 2, 3, 0 )
SELECT
  object_id,
  type_id,
  type_level
FROM
  table

enter image description here

Теперь я пытаюсь создать три новых столбца type_level_0_array, type_level_1_array, type_level_2_array для каждого объекта и объединить type_id соответствующего уровня типов в этот массив (я не ищу строку, разделенную запятыми).

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

+----+--------------------+--------------------+--------------------+
| id | type_level_0_array | type_level_1_array | type_level_2_array |
+----+--------------------+--------------------+--------------------+
| 1  | 2                  | 24,23              | 234                |
+----+--------------------+--------------------+--------------------+
| 2  | 3,4                | 34,46              | 465,349            |
+----+--------------------+--------------------+--------------------+

Есть ли способ сделать это?

Обновление:

Хотя кажется, что мой type_id имеет определенный шаблон, например типы уровня 0 имеют длину 1, типы уровня 1 имеют длину 2 и т. д. В моем реальном наборе данных такого шаблона нет. Определение уровня возможно только путем просмотра type_level любой строки.

Ответы [ 2 ]

0 голосов
/ 25 января 2019

Ниже для BigQuery Standard SQL

#standardSQL
SELECT object_id,
  ARRAY_AGG(DISTINCT IF(type_level = 0, type_id, NULL) IGNORE NULLS) AS type_level_0_array,
  ARRAY_AGG(DISTINCT IF(type_level = 1, type_id, NULL) IGNORE NULLS) AS type_level_1_array,
  ARRAY_AGG(DISTINCT IF(type_level = 2, type_id, NULL) IGNORE NULLS) AS type_level_2_array
FROM `project.dataset.table`
GROUP BY object_id    

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

#standardSQL
WITH `project.dataset.table` AS (
  SELECT 1 object_id, 234 type_id, 2 type_level UNION ALL
  SELECT 1, 23, 1 UNION ALL
  SELECT 1, 24, 1 UNION ALL
  SELECT 1, 2, 0 UNION ALL
  SELECT 1, 2, 0 UNION ALL
  SELECT 2, 34, 1 UNION ALL
  SELECT 2, 46, 1 UNION ALL
  SELECT 2, 465, 2 UNION ALL
  SELECT 2, 349, 2 UNION ALL
  SELECT 2, 4, 0 UNION ALL
  SELECT 2, 3, 0 )
SELECT object_id,
  ARRAY_AGG(DISTINCT IF(type_level = 0, type_id, NULL) IGNORE NULLS) AS type_level_0_array,
  ARRAY_AGG(DISTINCT IF(type_level = 1, type_id, NULL) IGNORE NULLS) AS type_level_1_array,
  ARRAY_AGG(DISTINCT IF(type_level = 2, type_id, NULL) IGNORE NULLS) AS type_level_2_array
FROM `project.dataset.table`
GROUP BY object_id   

с результатом

Row     object_id   type_level_0_array  type_level_1_array  type_level_2_array   
1       1           2                   24                  234  
                                        23       
2       2           4                   34                  349  
                    3                   46                  465  
0 голосов
/ 25 января 2019

Попробуй это. У меня работает.

Bigquery не позволит вам создать массив с нулевыми значениями в них, поэтому требуется IGNORE NULLS.

РЕДАКТИРОВАТЬ: я обновил код, чтобы быть основанным на столбце type_level

WITH table
 AS (
  SELECT 1 object_id, 234 type_id, 2 type_level UNION ALL
  SELECT 1, 23, 1 UNION ALL
  SELECT 1, 24, 1 UNION ALL
  SELECT 1, 2, 0 UNION ALL
  SELECT 1, 2, 0 UNION ALL
  SELECT 2, 34, 1 UNION ALL
  SELECT 2, 46, 1 UNION ALL
  SELECT 2, 465, 2 UNION ALL
  SELECT 2, 349, 2 UNION ALL
  SELECT 2, 4, 0 UNION ALL
  SELECT 2, 3, 0 )
SELECT
  ARRAY_AGG(CASE WHEN type_level = 0 THEN type_id ELSE NULL END IGNORE NULLS) AS type_level_0_array
  , ARRAY_AGG(CASE WHEN type_level = 1 THEN type_id ELSE NULL END IGNORE NULLS) AS type_level_1_array
  , ARRAY_AGG(CASE WHEN type_level = 2 THEN type_id ELSE NULL END IGNORE NULLS) AS type_level_2_array
FROM
  table
...