Найти сумму значений текущего месяца и предыдущего месяца - PullRequest
3 голосов
/ 07 октября 2019

У меня есть исходная таблица с деталями учетной записи сотрудника для каждого месяца, дата имеет тип String (yyyyMMdd). Попытка найти сумму значений текущего месяца и значений предыдущего месяца для каждой учетной записи.

Source data:

+-----------+-------------+-----------+----------+
|  date     | account     | division  |  amount  |
+-----------+-------------+-----------+----------+
| 20190331  | 123         | AB0       | 100      |
+-----------+-------------+-----------+----------+
| 20190331  | 123         | AB1       | 110      |
+-----------+-------------+-----------+----------+
| 20190331  | 123         | AB2       | 120      |
+-----------+-------------+-----------+----------+
| 20190228  | 123         | AB4       | 100      |
+-----------+-------------+-----------+----------+
| 20190228  | 123         | AB1       | 100      |
+-----------+-------------+-----------+----------+
| 20190228  | 123         | AB2       | 100      |
+-----------+-------------+-----------+----------+
| 20190131  | 123         | AB0       | 100      |
+-----------+-------------+-----------+----------+

побежал ниже запроса в Impala, но это возвращает мне те же результаты для текущего и предыдущего месяца.

select distinct * from (
SELECT 
sum(amount) over (partition BY account, a.date) AS asset_current,
sum(amount) over (partition BY account, from_unixtime(unix_timestamp(to_date(LAST_DAY(ADD_MONTHS(to_timestamp(data_as_of_date,'yyyyMMdd'),-1))),'yyyy-MM-dd'),'yyyyMMdd')) AS asset_previous,
     account,
     date,
FROM employee_assets a
)x ;

Ожидаемый результат:

+-----------+-------------+--------------------+----------------------+
|  date     | account     | current_month_sum  |  previous_month_sum  |
+-----------+-------------+--------------------+----------------------+
| 20190331  | 123         | 330                | 300                  |
+-----------+-------------+--------------------+----------------------+
| 20190228  | 123         | 300                | 100                  |
+-----------+-------------+--------------------+----------------------+
| 20190131  | 123         | 100                | 0                    |
+-----------+-------------+--------------------+----------------------+

Я использовал приведенный ниже запрос, но он возвращает asset_previous, как и месяцем ранее, если данные за предыдущий месяц недоступны.

SELECT
    x.*,
    LAG(current_month_sum, 1, 0) OVER(PARTITION BY account ORDER BY adate) previous_month_sum  
FROM (
    SELECT adate, account, SUM(amount) current_month_sum  
    FROM employee_assets
    GROUP BY adate, account
) x
ORDER BY adate DESC

например: у нас нет входных данных для 20181231 для счета 123, поэтому asset_prev за месяц январь должен быть 0, но запрос возвращает 500 (что является суммой за ноябрь'2018) Входные данные:

+-----------+-------------+-----------+----------+
|  date     | account     | division  |  amount  |
+-----------+-------------+-----------+----------+
| 20190331  | 123         | AB0       | 100      |
+-----------+-------------+-----------+----------+
| 20190331  | 123         | AB1       | 110      |
+-----------+-------------+-----------+----------+
| 20190331  | 123         | AB2       | 120      |
+-----------+-------------+-----------+----------+
| 20190228  | 123         | AB4       | 100      |
+-----------+-------------+-----------+----------+
| 20190228  | 123         | AB1       | 100      |
+-----------+-------------+-----------+----------+
| 20190228  | 123         | AB2       | 100      |
+-----------+-------------+-----------+----------+
| 20190131  | 123         | AB0       | 100      |
+-----------+-------------+-----------+----------+
| 20181130  | 123         | ABX       | 500      |
+-----------+-------------+-----------+----------+

Запрос возвращается:

+-----------+-------------+--------------------+----------------------+
|  date     | account     | current_month_sum  |  previous_month_sum  |
+-----------+-------------+--------------------+----------------------+
| 20190331  | 123         | 330                | 300                  |
+-----------+-------------+--------------------+----------------------+
| 20190228  | 123         | 300                | 100                  |
+-----------+-------------+--------------------+----------------------+
| 20190131  | 123         | 100                | 500                  |
+-----------+-------------+--------------------+----------------------+
| 20191131  | 123         | 500                | 0                    |
+-----------+-------------+--------------------+----------------------+

Ожидаемый результат:

+-----------+-------------+--------------------+----------------------+
|  date     | account     | current_month_sum  |  previous_month_sum  |
+-----------+-------------+--------------------+----------------------+
| 20190331  | 123         | 330                | 300                  |
+-----------+-------------+--------------------+----------------------+
| 20190228  | 123         | 300                | 100                  |
+-----------+-------------+--------------------+----------------------+
| 20190131  | 123         | 100                | 0                    |
+-----------+-------------+--------------------+----------------------+
| 20191131  | 123         | 500                | 0                    |
+-----------+-------------+--------------------+----------------------+

1 Ответ

3 голосов
/ 08 октября 2019

Вы можете использовать агрегацию во внутреннем запросе и использовать LAG() во внешнем запросе, чтобы получить значение предыдущего месяца в разделе account. Форма с тремя аргументами LAG() позволяет указать значение по умолчанию.

SELECT
    x.*,
    LAG(current_month_sum, 1, 0) OVER(PARTITION BY account ORDER BY adate) previous_month_sum  
FROM (
    SELECT adate, account, SUM(amount) current_month_sum  
    FROM employee_assets
    GROUP BY adate, account
) x
ORDER BY adate DESC

Примечание: date не является хорошим выбором для имени столбца, поскольку оно может конфликтовать с зарезервированным словом. Я переименовал этот столбец в adate в запросе.

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