Как удалить повторяющиеся строки при использовании array_agg в BigQuery - PullRequest
0 голосов
/ 11 февраля 2020

У меня есть следующие данные:

WITH data as (
  SELECT 18 AS value, 1 AS id, "A" AS other_value,
  UNION ALL SELECT 20 AS value, 1 AS id, "B",
  UNION ALL SELECT 22 AS value, 2 AS id, "C"
  UNION ALL SELECT 30 AS value, 3 AS id, "A"
  UNION ALL SELECT 37 AS value, 2 AS id, "B"
  UNION ALL SELECT 31 AS value, 2 AS id, "C"
  UNION ALL SELECT 42 AS value, 1 AS id, "D"
)

Я использую следующий запрос

select
   FIRST_VALUE(id) over w1 as id
 , ARRAY_AGG(value) over w1  as data
 , FIRST_VALUE(other_value) over w1 as first_other_data
 , LAST_VALUE(other_value) over w1  as last_other_data
from data
WINDOW w1 as (PARTITION BY id order by value ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)

И я получаю

id  data  first_other_data  last_other_data 
1   18    A                 D 
    20
    42
1   18    A                 D
    20
    42
1   18    A                 D
    20
    42
2   22    C                 B
    31
    37
2   22    C                 B
    31
    37
2   22    C                 B
    31
    37
3   30    A                 A

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

id  data  first_other_data  last_other_data     
1   18     A                 D
    20
    42
2   22     C                 B
    31
    37
3   30     A                 A

Я нашел похожие вопросы, но не совсем в этом случае. Спасибо РЕДАКТИРОВАТЬ: В моей попытке упростить сценарий для этого вопроса SO я вынул некоторые важные компоненты. Я изменил это с более точной версией моей проблемы.

Ответы [ 2 ]

2 голосов
/ 11 февраля 2020

Я думаю, что вы все еще хотите агрегирование с группировкой :) Так как значения и other_value, кажется, связаны (вы упорядочиваете по значению в окне, чтобы выбрать other_value), я бы просто поместил их в массив:

WITH data as (
  SELECT 18 AS value, 1 AS id, "A" AS other_value,
  UNION ALL SELECT 20 AS value, 1 AS id, "B",
  UNION ALL SELECT 22 AS value, 2 AS id, "C"
  UNION ALL SELECT 30 AS value, 3 AS id, "A"
  UNION ALL SELECT 37 AS value, 2 AS id, "B"
  UNION ALL SELECT 31 AS value, 2 AS id, "C"
  UNION ALL SELECT 42 AS value, 1 AS id, "D"
)

select 
  id,
  array_agg(struct(value, other_value)) as data
from data
group by id

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

WITH data as (
  SELECT 18 AS value, 1 AS id, "A" AS other_value,
  UNION ALL SELECT 20 AS value, 1 AS id, "B",
  UNION ALL SELECT 22 AS value, 2 AS id, "C"
  UNION ALL SELECT 30 AS value, 3 AS id, "A"
  UNION ALL SELECT 37 AS value, 2 AS id, "B"
  UNION ALL SELECT 31 AS value, 2 AS id, "C"
  UNION ALL SELECT 42 AS value, 1 AS id, "D"
), 
temp as (
  select 
    id,
    array_agg(struct(value, other_value)) as data
  from data
  group by id
)
select 
  id,
  array(select value from unnest(data)) as data,
  (select other_value from unnest(data) order by value ASC limit 1) first_other_data,
  (select other_value from unnest(data) order by value DESC limit 1) last_other_data
from temp
0 голосов
/ 11 февраля 2020

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

#standardSQL
SELECT ANY_VALUE(t).* FROM (
  SELECT
     FIRST_VALUE(id) OVER w1 AS id
   , ARRAY_AGG(value) OVER w1  AS data
   , FIRST_VALUE(other_value) OVER w1 AS first_other_data
   , LAST_VALUE(other_value) OVER w1  AS last_other_data
  FROM data
  WINDOW w1 AS (PARTITION BY id ORDER BY value ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)
) t
GROUP BY FORMAT('%t', t)  

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

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...