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

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

использовал приведенный ниже запрос, но он возвращает 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) Входные данные:

+-----------+-------------+-----------+----------+
|  adate    | 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      |
+-----------+-------------+-----------+----------+

Вывод запроса:

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

Ожидаемый вывод:

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

Ответы [ 3 ]

2 голосов
/ 12 октября 2019

попробуйте ниже Query

select adate ,CURRENT_AMT ,
     case when mon-1<>PREVIDATE then 0 else PREVI end as PREVIOUS_AMT
    from(
    select adate, 
    sum(amount) CURRENT_AMT,
    lag(sum(amount),1,0)over(order by adate)PREVI,
    (cast (substr(adate,5,2) as integer)) mon,
    lag(cast (substr(adate,5,2) as integer),1,1) over(order by adate)PREVIDATE
    from  stack_demo_q group by adate order by adate
    )
1 голос
/ 11 октября 2019
select adate,amt as current_month_sum,case when mon=1 and (monthh-1=monh) then PREVI when  mon-1<>PREVIDATE then 0   else PREVI end as previous_month_sum
from(
select adate,sum(amount) amt,lag(sum(amount),1,0)over(order by adate)PREVI,
(cast (substr(adate,5,2) as integer)) mon,
lag(cast (substr(adate,5,2) as integer),1,1) over(order by adate)PREVIDATE,
lag (cast (substr(adate,1,4) as integer),1,1) over (order by adate) monh,
(cast (substr(adate,1,4) as integer)) as monthh
from  stack_demo_q group by adate order by adate);
0 голосов
/ 11 октября 2019

Вы можете использовать предложение range, но с аналитической функцией sum следующим образом:

- обновлено -

SQL> WITH employee_assets  (adate    , account     , division  ,  amount )
  2  AS
  3  (SELECT  TO_DATE('20190331','YYYYMMDD')  , 123         , 'AB0'       , 100 FROM DUAL UNION ALL
  4  SELECT  TO_DATE('20190331','YYYYMMDD')  , 123         , 'AB1'       , 110 FROM DUAL UNION ALL
  5  SELECT  TO_DATE('20190331','YYYYMMDD')  , 123         , 'AB2'       , 120 FROM DUAL UNION ALL
  6  SELECT  TO_DATE('20190228','YYYYMMDD')  , 123         , 'AB4'       , 100 FROM DUAL UNION ALL
  7  SELECT  TO_DATE('20190228','YYYYMMDD')  , 123         , 'AB1'       , 100 FROM DUAL UNION ALL
  8  SELECT  TO_DATE('20190228','YYYYMMDD')  , 123         , 'AB2'       , 100 FROM DUAL UNION ALL
  9  SELECT  TO_DATE('20190131','YYYYMMDD')  , 123         , 'AB0'       , 100 FROM DUAL UNION ALL
 10  SELECT  TO_DATE('20181130','YYYYMMDD')  , 123         , 'ABX'       , 500 FROM DUAL)
 11  SELECT
 12      X.ADATE, X.ACCOUNT, X.CURRENT_MONTH_SUM,
 13      SUM(CURRENT_MONTH_SUM) OVER(
 14          PARTITION BY ACCOUNT
 15          ORDER BY
 16              AMONTH
 17          RANGE BETWEEN 1 PRECEDING AND 1 PRECEDING
 18      ) PREVIOUS_MONTH_SUM
 19  FROM
 20      (
 21          SELECT
 22              ADATE,
 23              ACCOUNT,
 24              SUM(AMOUNT) CURRENT_MONTH_SUM,
 25              TO_NUMBER(TO_CHAR(ADATE, 'YYYYMM')) AS AMONTH
 26          FROM
 27              EMPLOYEE_ASSETS
 28          GROUP BY
 29              ADATE,
 30              ACCOUNT
 31      ) X
 32  ORDER BY
 33      ADATE DESC
 34  ;

ADATE        ACCOUNT CURRENT_MONTH_SUM PREVIOUS_MONTH_SUM
--------- ---------- ----------------- ------------------
31-MAR-19        123               330                300
28-FEB-19        123               300                100
31-JAN-19        123               100
30-NOV-18        123               500

SQL>

Cheers !!

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