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