#sql #google-bigquery
#sql #google-bigquery
Вопрос:
У меня есть таблица с именем user_state со столбцами user_ID, account_id, Balance, Date . У каждого идентификатора пользователя может быть несколько учетных записей. Пример таблицы выглядит следующим образом: https://i.stack.imgur.com/w4odf.png вы можете создать таблицу с помощью скрипта:
CREATE TABLE USER_STATE (USER_ID int, ACCOUNT_ID int, SNAPSHOT_DATE DATE, BALANCE float);
INSERT INTO USER_STATE(USER_ID,ACCOUNT_ID,SNAPSHOT_DATE,BALANCE) VALUES(23,1 ,'2016-07-01', 50);
INSERT INTO USER_STATE(USER_ID,ACCOUNT_ID,SNAPSHOT_DATE,BALANCE) VALUES(23,2 ,'2016-07-01', 50);
INSERT INTO USER_STATE(USER_ID,ACCOUNT_ID,SNAPSHOT_DATE,BALANCE) VALUES(23,2 ,'2016-07-05', 80);
INSERT INTO USER_STATE(USER_ID,ACCOUNT_ID,SNAPSHOT_DATE,BALANCE) VALUES(23,1, '2016-07-27', 150);
INSERT INTO USER_STATE(USER_ID,ACCOUNT_ID,SNAPSHOT_DATE,BALANCE) VALUES(23,1,'2016-07-31', 200);
INSERT INTO USER_STATE(USER_ID,ACCOUNT_ID,SNAPSHOT_DATE,BALANCE) VALUES(23,1, '2016-08-18', 150);
INSERT INTO USER_STATE(USER_ID,ACCOUNT_ID,SNAPSHOT_DATE,BALANCE) VALUES(23,2,'2016-08-21', 250);
INSERT INTO USER_STATE(USER_ID,ACCOUNT_ID,SNAPSHOT_DATE,BALANCE) VALUES(23,1,'2016-08-21', 250);
INSERT INTO USER_STATE(USER_ID,ACCOUNT_ID,SNAPSHOT_DATE,BALANCE) VALUES(44,1, '2016-06-01', 10);
INSERT INTO USER_STATE(USER_ID,ACCOUNT_ID,SNAPSHOT_DATE,BALANCE) VALUES(44,2, '2016-06-01', 20);
INSERT INTO USER_STATE(USER_ID,ACCOUNT_ID,SNAPSHOT_DATE,BALANCE) VALUES(44, 1,'2016-06-05', 40);
INSERT INTO USER_STATE(USER_ID,ACCOUNT_ID,SNAPSHOT_DATE,BALANCE) VALUES(44,1, '2016-06-27', 90);
INSERT INTO USER_STATE(USER_ID,ACCOUNT_ID,SNAPSHOT_DATE,BALANCE) VALUES(44,1, '2016-06-31', 300);
INSERT INTO USER_STATE(USER_ID,ACCOUNT_ID,SNAPSHOT_DATE,BALANCE) VALUES(44,1, '2016-09-18', 400);
INSERT INTO USER_STATE(USER_ID,ACCOUNT_ID,SNAPSHOT_DATE,BALANCE) VALUES(44,1, '2016-09-21', 200);
INSERT INTO USER_STATE(USER_ID,ACCOUNT_ID,SNAPSHOT_DATE,BALANCE) VALUES(44,2, '2016-09-21', 200);
Я хотел бы получить эти значения в месяц для каждого пользователя:
- first_date месяца и sum_balance за первое число месяца для каждого пользователя.
- last_date месяца и sum_balance для последней даты этого месяца для каждого пользователя.
- ave_balance за каждый месяц для каждого пользователя.
Конечный результат должен выглядеть так: https://i.stack.imgur.com/Fyjes.png
Одно из решений — получить элемент, который я перечислил, и который мне нужен в месяц для каждого пользователя отдельно, и объединить таблицы, есть ли более эффективное и простое решение для этого?
Спасибо, Бикрам
Ответ №1:
Хммм . . . агрегируйте по дате моментального снимка и пользователю, а затем по пользователю и месяцу:
select user_id, date_trunc(snapshot_date, month) as yyyymm,
min(snapshot_date) as first_date,
array_agg(balance order by snapshot_date limit 1)[ordinal(1)] as first_balance,
max(snapshot_date) as first_date,
array_agg(balance order by snapshot_date desc limit 1)[ordinal(1)] as last_balance,
avg(balance)
from (select user_id, snapshot_date, sum(balance) as balance
from user_state u
group by 1, 2
) u
group by 1, 2;
Комментарии:
1. Спасибо за решение, оно работает, однако есть опечатка eesc, вместо этого оно должно быть desc. Также можете ли вы объяснить, что делает этот [порядковый номер (1)] ?