Может ли BigQuery отбрасывать строки промежуточных итогов при ответе на запрос ROLLUP

Когда я запрашиваю BQ с ROLLUP по потенциально большому набору поля критериев группировки (в данном случае campaign_group_id)

Например:

SELECT
  campaign_group_id AS campaign_group_id,
  DATE(DATE_ADD(TIME, 3, 'HOUR')) AS DAY,
  SUM(impressions) AS imps
FROM
  [browser_traffic.2016_05_28],
  [browser_traffic.2016_05_29]
WHERE
  ( DATE_ADD( TIME, 3, "HOUR") >= '2016-05-28 00:00:00'
    AND DATE_ADD( TIME, 3, "HOUR") < '2016-05-30 00:00:00' )
GROUP EACH BY ROLLUP (campaign_group_id, DAY)
ORDER BY DAY ASC, campaign_group_id ASC
LIMIT 500

BQ возвращает много строк с промежуточными итогами, что неприменимо в моем случае использования:

+-------------------+------+-----------+
| campaign_group_id | day  |   imps    |
+-------------------+------+-----------+
|              NULL | NULL | 158423933 |
|                61 | NULL |         0 |
|               496 | NULL |     79870 |
|               497 | NULL |     10492 |
|               809 | NULL |         0 |
|               936 | NULL |      2451 |
|               937 | NULL |         0 |
|               940 | NULL |      6844 |
|               942 | NULL |    207685 |
|               946 | NULL |         0 |
|               961 | NULL |         0 |
|               975 | NULL |     16167 |
|               976 | NULL |     15767 |
|              1018 | NULL |         0 |
|              1020 | NULL |         0 |
|              1022 | NULL |    766875 |
|              1039 | NULL |    355765 |
...

Мне нужно как-то уменьшить промежуточные итоговые строки из результата, но оставить нетронутую общую итоговую строку (которая является первой строкой в ​​приведенном выше результате)

Возможно ли, что BQ возвращает только строку общего итога для выбранных полей?


person Andrew    schedule 30.05.2016    source источник


Ответы (3)


Вы можете отфильтровать результат запроса с помощью другого оператора SELECT:

SELECT campaign_group_id, day, imps 
FROM (
    ... your rollup query with LIMIT removed ...
)
WHERE (day IS NOT NULL) OR (campaign_group_id IS NULL)
LIMIT 500
person Michael Entin    schedule 31.05.2016
comment
Спасибо @Michael - я думаю, это именно то, что мне нужно! - person Andrew; 31.05.2016
comment
Протестировано сегодня ваше предложение, но если у меня будет больше столбцов группировки, результат также будет содержать промежуточные строки. Будет больше проблем, если такие столбцы допускают значение NULL, что в точности входит в мои варианты использования ... - person Andrew; 31.05.2016
comment
используйте GROUPING (), прокрутите до полного ответа - person Felipe Hoffa; 01.06.2016

Если вас интересуют общие итоги - вам, скорее всего, не понадобится ROLLUP

Скорее вы можете рассмотреть обычную GROUP BY, как показано ниже

SELECT
  DATE(DATE_ADD(TIME, 3, 'HOUR')) AS DAY,
  SUM(impressions) AS imps
FROM
  [browser_traffic.2016_05_28],
  [browser_traffic.2016_05_29]
WHERE
  ( DATE_ADD( TIME, 3, "HOUR") >= '2016-05-28 00:00:00'
    AND DATE_ADD( TIME, 3, "HOUR") < '2016-05-30 00:00:00' )
GROUP 1
ORDER BY DAY ASC
LIMIT 500
person Mikhail Berlyant    schedule 30.05.2016
comment
Я обновил свой вопрос. Меня также интересуют строки общего итога и данных, но не строки промежуточных итогов. Спасибо за ответ - person Andrew; 31.05.2016

Обратите внимание, что функция GROUPING () тоже существует и поможет вам в этом:

SELECT year, name, SUM(number) s,
       GROUPING(year) is_grouping_year, 
       GROUPING(name) is_grouping_name
FROM [bigquery-public-data:usa_names.usa_1910_2013] 
WHERE name IN ('John', 'Jovana')
AND year BETWEEN 2012 AND 2013
GROUP BY ROLLUP(name, year)
ORDER BY year, name

year    name    s       is_grouping_year    is_grouping_name     
null    null    21182   1                   1    
null    John    21164   1                   0    
null    Jovana  18      1                   0    
2012    John    10576   0                   0    
2012    Jovana  18      0                   0    
2013    John    10588   0                   0

В основном вы запрашиваете строки, где is_grouping_year и is_grouping_name либо 0, либо 1.

Из документов:

При использовании функции ROLLUP вы можете использовать функцию GROUPING, чтобы различать строки, которые были добавлены из-за функции ROLLUP, и строки, которые фактически имеют значение NULL для ключа группы.

https://cloud.google.com/bigquery/query-reference#groupby

person Felipe Hoffa    schedule 01.06.2016
comment
Да, был там ... В моем запросе дата вычисляется в поле, например DATE (DATE_ADD (TIME, 3, 'HOUR')), поэтому он недоступен для GROUPING. Но я стараюсь заключить это в подзапрос. - person Andrew; 01.06.2016