Bigquery / Стандартный SQL: Как я могу объединить все столбцы (около 100 столбцов) с помощью sum ()? - PullRequest
0 голосов
/ 11 июня 2018

Я ищу решение для агрегирования таблицы Bigquery с около 100 столбцами, используя функцию sum ().Но следующий запрос недопустим в стандартном SQL Bigquery.

select sum(*)
from `dataset.Intermediate_Tables.eventCat_dummies`
group by Id

Причина, по которой я хочу выполнить такой тип агрегации в Bigquery, заключается в его способности обрабатывать большие объемы данных.Я пытался сделать то же самое в ноутбуке Jupyter, но каждый раз это не удавалось.Это может быть из-за большого размера данных (7,3 ГиБ CSV-файл).Код, который я пробовал, выглядит следующим образом:

df_type = type_dummies.groupby('Id', sort=False).sum()

Кто-нибудь может дать какие-либо предложения и / или альтернативы тому, как я могу получить агрегированные данные этого большого набора данных?

ОБНОВЛЕНИЕ С ВХОДОМ И ВЫХОДОМ ОБРАЗЦА

Входные данные

Id col1 col2 col3 col4
1  0    0    0    1
2  0    1    1    1
1  1    0    0    0
4  0    0    0    0
19 0    0    0    0
2  1    1    1    1

Требуемый выход

Id col1_sum col2_sum col3_sum col4_sum
1  1        0        0        1
2  1        2        2        2
4  0        0        0        0
19 0        0        0        0

В моем исходном наборе данных 100 столбцов и 40 миллионов строк.

1 Ответ

0 голосов
/ 11 июня 2018

Ниже приведен пример для BigQuery StandardSQL

#standardSQL
WITH `project.dataset.table` AS (
  SELECT 1 id, 1 a, 2 b, 3 c UNION ALL
  SELECT 1, 4, 5, 6 UNION ALL
  SELECT 2, 7, 8, 9
)
SELECT id, 
  SUM((
    SELECT SUM(CAST(SPLIT(pair, ':')[SAFE_OFFSET(1)] AS INT64)) 
    FROM UNNEST(SPLIT(REGEXP_REPLACE(TO_JSON_STRING(t), r'[{}]', ''))) pair 
    WHERE SPLIT(pair, ':')[SAFE_OFFSET(0)] != '"id"'
  )) val
FROM `project.dataset.table` t
GROUP BY id    

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

Row id  val  
1   1   21   
2   2   24     

Как вы можете видеть - выше не зависит от количества столбцов
Также предполагается, чтовсе столбцы, кроме id, должны быть суммированы.если у вас есть больше столбцов, которые нужно исключить - вы можете настроить WHERE предложение соответственно

Обновление на основе предоставленных данных
Таким образом, вы хотите суммировать каждый столбец (изначально я читал ваш вопроскак если бы вы хотели сложить все значения столбца вместе по id)

#standardSQL
WITH `project.dataset.table` AS (
  SELECT 1 id, 1 a, 2 b, 3 c UNION ALL
  SELECT 1, 4, 5, 6 UNION ALL
  SELECT 2, 7, 8, 9
)
SELECT id, 
  REPLACE(SPLIT(pair, ':')[SAFE_OFFSET(0)], '"', '')  col,
  SUM(CAST(SPLIT(pair, ':')[SAFE_OFFSET(1)] AS INT64)) val
FROM (
  SELECT id, 
    ARRAY(
      SELECT pair
      FROM UNNEST(SPLIT(REGEXP_REPLACE(TO_JSON_STRING(t1), r'[{}]', ''))) pair 
      WHERE SPLIT(pair, ':')[SAFE_OFFSET(0)] != '"id"'
    ) arr
  FROM `project.dataset.table` t1
) t2,
UNNEST(arr) pair
GROUP BY id, col
ORDER BY id, col

это даст вам результат ниже

Row id  col val  
1   1   a   5    
2   1   b   7    
3   1   c   9    
4   2   a   7    
5   2   b   8    
6   2   c   9    

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

Тем не менее, если вы хотите изменить этот результат - см. https://stackoverflow.com/a/35808045/5221944

...