Big Query SQL - группировка по всем возможным уровням агрегации - PullRequest
0 голосов
/ 29 мая 2018

Допустим, у меня есть таблица со столбцами value, dim1, ..., dim 10, и я хочу получить медиану для всех возможных группировок по столбцам dim1, ..., dim10.то есть по всем подгруппам, всем подгруппам в любых 9 измерениях, любых 8 ...

Я могу сделать

SELECT * FROM
( 
    SELECT 
        APPROX_QUANTILES(value, 100)[SAFE_ORDINAL(50)] as median,
        dim1, ..., dim10
    FROM table
    GROUP BY dim1, ..., dim10
)
UNION ALL
( 
    SELECT 
        APPROX_QUANTILES(value, 100)[SAFE_ORDINAL(50)] as median,
        dim1, ..., dim9
        NULL as dim10
    FROM table
    GROUP BY dim1, ..., dim9
)
UNION ALL
... --2^10 subtables

, но это довольно долго, особенно если table вычисляется на лету,Есть ли лучший способ?

Я работаю с большим запросом, но ответ может быть не только для большого запроса

Ответы [ 2 ]

0 голосов
/ 30 мая 2018

Вот мое временное решение, которое, похоже, делает то, что делает CUBE:

CREATE TEMPORARY FUNCTION makeGroups(group_names ARRAY<STRING>)
RETURNS ARRAY<STRING>
LANGUAGE js AS """
  var res = [];
  var n = 1 << group_names.length;
  for(var i=0; i<n; i++) {
    res.push(group_names.map(function(g, idx) { return (i >> idx) % 2 == 1 ? (g || 'null') : 'any' }).join(':::'));
  }
  return res;
""";

WITH data AS
(
  SELECT
    value,
    makeGroups([dim1, ..., dim10]) AS group_names
  FROM
    table
)

SELECT 
  SUM(1) as counts,
  APPROX_QUANTILES(value, 100)[SAFE_ORDINAL(50)] as median
  group_name
FROM
(
  SELECT
    value,
    group_name
  FROM data
  CROSS JOIN UNNEST(data.group_names) as group_name
)
GROUP BY
  group_name

Я мог бы сопоставить имя группы, которое выглядит как dim1_value::...::dim10_value, с колонками, но я вроде как различаю NULL от исходного значения (здесь 'null') и от агрегации (здесь 'any')

0 голосов
/ 29 мая 2018

Я полагаю, вы хотите GROUP BY ROLLUP:

SELECT APPROX_QUANTILES(value, 100)[SAFE_ORDINAL(50)] as median,
       dim1, ..., dim10
FROM table
GROUP BY ROLLUP(dim1, ..., dim10);

Это доступно как в стандартном, так и в устаревшем SQL (и это, вероятно, объясняет, почему более распространенный синтаксис GROUPING SETS неб).

...