当缺少前一个月的直接数据时,查找当前和前一个月的总和值

时间:2019-10-11 02:06:51

标签: oracle hive impala

我有一个源表,其中包含每个月的员工帐户详细信息,日期是字符串类型(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

例如:我们没有帐户123的20181231输入数据,因此月份1的asset_prev应该为0,但查询返回500(这是2018年11月的金额) 输入数据:

+-----------+-------------+-----------+----------+
|  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 个答案:

答案 0 :(得分:2)

在查询下面尝试

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 :(得分:1)

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);

答案 2 :(得分:0)

您可以使用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>

干杯!