使用oracle获取过去12个月的计数及其差异

3pvhb19x  于 2021-08-13  发布在  Java
关注(0)|答案(2)|浏览(490)
  1. with sales as
  2. (
  3. select COUNT(sale) As Number_of_sale,
  4. TO_CHAR(dates,'YYYY-MON') As Period
  5. from orders
  6. where dates between date '2020-03-01' and date '2020-03-31'
  7. group by TO_CHAR(dates,'YYYY-MON')
  8. union all
  9. select COUNT(sale) As Number_of_sale,
  10. TO_CHAR(dates,'YYYY-MON') As Period
  11. from orders
  12. where dates between date '2020-04-01' and date '2020-04-30'
  13. group by TO_CHAR(dates,'YYYY-MON')
  14. )
  15. select Number_of_sale, period,
  16. case when to_char(round((Number_of_sale-lag(Number_of_sale,1, Number_of_sale) over (order by period ))/ Number_of_sale*100,2), 'FM999999990D9999') <0
  17. then to_char(round(abs( Number_of_sale-lag(Number_of_sale,1, Number_of_sale) over (order by period ))/ Number_of_sale*100,2),'FM999999990D9999')||'%'||' (Increase) '
  18. when to_char(round((Number_of_sale-lag(Number_of_sale,1,Number_of_sale) over (order by period ))/Number_of_sale*100,2),'FM999999990D9999')>0
  19. then to_char(round(abs(Number_of_sale-lag(Number_of_sale,1, Number_of_sale) over (order by period ))/Number_of_sale*100,2),'FM999999990D9999')||'%'||' (Decrease) '
  20. END as variances
  21. from sales
  22. order by variances asc;

我得到的输出

  1. Number_of_sale | Period |Variances
  2. 50 | 2020-Mar | 100%(increase)
  3. 100 | 2020-Apr | Null

输出ineed:- i 需要过去12个月和他们的方差交叉积水的最后一个月。

lsmepo6l

lsmepo6l1#

查询的with位包含一些冗余的联合,它可能会排除时间段结束的日期。请考虑以下问题:

  1. select COUNT(sale) As Number_of_sale,
  2. TO_CHAR(dates,'YYYY-MON') As Period
  3. from orders
  4. where dates >= date '2019-03-01' and dates < date '2020-03-01'
  5. group by TO_CHAR(dates,'YYYY-MON')

你不需要将连续的日期范围合并在一起,只要使用一个更大的日期范围-你的抱怨是你只有两个月的时间,但这就是你所要求的(3月1日至3月31日,4月1日至4月30日为两个月)

cidc1ykv

cidc1ykv2#

首先,您需要学习如何使用日期作为日期,只有在极少数情况下才需要转换为字符串(除了最终显示结果)。这不是其中之一。你所拥有的一切都可以当作约会。你抱怨说你想要12个月,但你的查询只选择了2个月。如果你想要最后12个,你必须选择全部12个。你说你想要差异,但你不是在计算统计差异,而是在计算月与月之间的差异(如果一个月与前一个月的差异有多大)。

  1. with parms as (select trunc(date '&period_end_date','mon') dt from dual)
  2. , sales as
  3. ( select count(*) cnt
  4. , trunc(dates,'mon') period
  5. from orders
  6. cross join parms
  7. where trunc(dates,'mon') between add_months(dt, -12)
  8. and last_day(dt)
  9. group by trunc(dates,'mon')
  10. )
  11. select to_char(period, 'yyyy-Mon') period
  12. , cnt number_of_sales
  13. , to_char (round(abs(cnt - lag(cnt) over (order by period)) / cnt*100,2),'FM999999990D9999') ||
  14. case when cnt - lag(cnt) over (order by period) < 0 then ' %(Increase)'
  15. when cnt - lag(cnt) over (order by period) > 0 then ' %(Decrease)'
  16. else null
  17. end variances
  18. from sales
  19. order by variances asc;

parms cte(在oracle的“子查询分解”中)的工作原理基本上是因为我很懒,不想多次输入参数值。但它还有一个优点,即不管实际输入的日期是多少,它都会“返回”当月1日。sales cte统计从前12个月(加上月份(dt,-12))到参数日期的最后一天(最后一天(dt))的每个月的销售额。每个功能都会自动调整2月29日和不同月份的天数。它在将dates列截短到每月的第一个月后,获取每个月的销售计数。
然后,主查询使用一个简化的案例计算月与月之间的差异,以确定增加或减少(保持不变,但我认为它可能会被反转和/或您需要超前而不是滞后)。
免责声明:因为您实际上没有提供表定义而不是示例数据,所以它没有经过测试。

展开查看全部

相关问题