BigQuery - удаляет дубликаты из массива - PullRequest
1 голос
/ 26 марта 2020

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

SELECT SUM(views) views, title_group
FROM `fh-bigquery.wikipedia_v3.pageviews_2019`
CROSS JOIN
UNNEST([
    CASE WHEN (title LIKE '%game%') 
    THEN 'games_group' END, 
    CASE WHEN (title LIKE '%sport%') 
    THEN 'sports_group' END
]) AS title_group
WHERE DATE(datehour) BETWEEN '2019-01-01' AND '2019-01-10'AND wiki='en'
GROUP BY title_group

Вот результат:

views       ...   title_group
3414469869  ... 
4355264     ...   games_group
1361074     ...   sports_group

Тем не менее, номер 3414469869 для просмотров страницы, которые не принадлежат ни к одной группе, неверны. В самом деле, когда заголовок не содержит слова «игра» (или «спорт»), мы получаем UNNEST([null, "sports_group"]) (или UNNEST(["games_group", null])), поэтому мы все равно считаем количество просмотров для нулевой группы. Если заголовок не содержит ни «game», ни «sport», количество просмотров даже считается дважды.

Есть ли способ удалить дубликаты из массива?

Ответы [ 2 ]

2 голосов
/ 26 марта 2020

Как насчет добавления другой группы?

SELECT SUM(views) views, title_group
FROM `fh-bigquery.wikipedia_v3.pageviews_2019` CROSS JOIN
     UNNEST([CASE WHEN title LIKE '%game%' THEN 'games_group' END, 
             CASE WHEN title LIKE '%sport%' THEN 'sports_group' END,
             CASE WHEN title NOT LIKE '%game%' AND title NOT LIKE '%sport%' THEN 'Neither' END
            ]) AS title_group
WHERE DATE(datehour) BETWEEN '2019-01-01' AND '2019-01-10' AND
      wiki = 'en' AND
      title_group IS NOT NULL
GROUP BY title_group;

Примечание. Это не учитывает NULL заголовки. Я не знаю, важно ли это.

Однако я бы сформулировал это, используя два столбца:

SELECT (title LIKE '%game%') as is_game,
       (title LIKE '%sport%') as is_sport,
       SUM(views)
FROM `fh-bigquery.wikipedia_v3.pageviews_2019`
WHERE DATE(datehour) BETWEEN '2019-01-01' AND '2019-01-10' AND
      wiki = 'en' AND
      title_group IS NOT NULL
GROUP BY is_game, is_sport;

Это не возвращает те же строки, что и у вас - игры и спорт разделены на два ряда. Но вы можете видеть комбинации.

РЕДАКТИРОВАТЬ:

Теперь, когда я думаю об этом, вы просто хотите LEFT JOIN:

SELECT g.title_group, SUM(pv.views) as views, 
FROM `fh-bigquery.wikipedia_v3.pageviews_2019` pv LEFT JOIN
     (SELECT '%game%' as pattern, 'games_group' as title_group UNION ALL
      SELECT '%sport%', 'sports_group' as title_group UNION ALL
     ) g
     ON pv.title LIKE g.pattern
WHERE DATE(datehour) BETWEEN '2019-01-01' AND '2019-01-10' AND
      wiki = 'en' AND
GROUP BY g.title_group;
0 голосов
/ 26 марта 2020

Ниже для BigQuery Standard SQL

#standardSQL
SELECT SUM(views) views, title_group
FROM `fh-bigquery.wikipedia_v3.pageviews_2019`,
UNNEST(
    CASE WHEN REGEXP_CONTAINS(title, r'game|sport') THEN 
      [
        CASE WHEN (title LIKE '%game%') THEN 'games_group' END,
        CASE WHEN (title LIKE '%sport%') THEN 'sports_group' END
      ]
      ELSE ['other']
    END
) AS title_group
WHERE DATE(datehour) BETWEEN '2019-01-01' AND '2019-01-10'AND wiki='en'
AND   title_group IS NOT NULL
GROUP BY title_group
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...