BigQuery groupby, добавьте строку с количеством 0 для переменной groupby, если строк не найдено - PullRequest
1 голос
/ 28 октября 2019

Новичок в bigquery, и у меня есть проблема, которая, на мой взгляд, широко применима для множества различных групповых / манипуляций с данными. Любая помощь с благодарностью! Я запускаю следующий запрос, который группирует по команде, игре и по зонам, и возвращает счетчик для каждого:

SELECT
  rebounds.team_id,
  rebounds.game_id,
  CASE
    WHEN distance < 4 THEN 'zone1'
    WHEN NOT some_bool THEN 'zone2'
    WHEN distance >= 4 and distance2 < 12 THEN 'zone3'
    WHEN some_bool AND distance >= 4 THEN 'zone4'
  END AS this_zone,
  COUNT(*) AS my_count
FROM t1
GROUP BY 1,2,3

И я получаю следующую таблицу (показывающую для одной комбинации game_id / team_id для простоты, чтобы подчеркнутьвопрос):

team_id game_id this_zone my_count
     12      15     zone1        5
     12      15     zone2        3

В приведенном выше примере не было никаких наблюдений, которые соответствовали бы критериям для zone3, и в результате таблица вернула только две строки для этой комбинации game_id + team_id. Однако я хотел бы иметь 3-ю строку, чтобы таблица выглядела следующим образом:

team_id game_id this_zone my_count
     12      15     zone1        5
     12      15     zone2        3
     12      15     zone3        2
     12      15     zone4        0

Возможно ли это, чтобы указать одну из переменных groupby (в данном случае this_zone), и иметьbigquery создать строку со счетчиком 0, если счет равен нулю?

РЕДАКТИРОВАТЬ : я обновил CASE WHEN, чтобы более точно отражать сложность создания зон. Короче говоря, они полагаются на два разных числовых значения (расстояние и расстояние2 в этом примере), а также логическое значение (some_bool)

Ответы [ 2 ]

2 голосов
/ 28 октября 2019

Соединение с подходом календарной таблицы должно работать здесь:

WITH zones AS (
    SELECT 'zone1' AS zone UNION ALL
    SELECT 'zone2' UNION ALL
    SELECT 'zone3' UNION ALL
    SELECT 'zone4'
)

SELECT
    t.team_id,
    t.game_id,
    z.zone AS this_zone,
    COALESCE(COUNT(t2.game_id), 0) AS my_count
FROM zones z
CROSS JOIN (SELECT DISTINCT team_id, game_id FROM t1) t1
LEFT JOIN
(
    SELECT team_id, game_id,
        CASE WHEN distance < 4 THEN 'zone1'
             WHEN NOT some_bool THEN 'zone2'
             WHEN distance >= 4 and distance2 < 12 THEN 'zone3'
             WHEN some_bool AND distance >= 4 THEN 'zone4'
        END AS this_zone
    FROM t1
) t2
    ON t2.team_id = t1.team_id AND
       t2.game_id = t1.game_id AND
       t2.this_zone = z.zone
GROUP BY
    t1.team_id,
    t1.game_id,
    z.zone
ORDER BY
    t1.team_id,
    t1.game_id,
    z.zone;
1 голос
/ 28 октября 2019

Ниже для BigQuery Standard SQL

#standardSQL
SELECT team_id, game_id, this_zone, IFNULL(my_count, 0) AS my_count
FROM (
  SELECT DISTINCT
    rebounds.team_id,
    rebounds.game_id, 
    this_zone
  FROM t1, UNNEST(['zone1', 'zone2', 'zone3', 'zone4']) this_zone
) A 
LEFT JOIN (
  SELECT
    rebounds.team_id,
    rebounds.game_id,
    CASE
      WHEN distance < 4 THEN 'zone1'
      WHEN NOT some_bool THEN 'zone2'
      WHEN distance >= 4 AND distance2 < 12 THEN 'zone3'
      WHEN some_bool AND distance >= 4 THEN 'zone4'
    END AS this_zone,
    COUNT(*) AS my_count
  FROM t1
  GROUP BY 1,2,3
) B
USING (team_id, game_id, this_zone)   

Выше достаточно универсально и не зависит от того, насколько сложна ваша логика или нет - вы просто генерируете все ожидаемые строки (подзапрос A) и оставляете соединение с нимВаш оригинальный запрос - и все!

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