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

3pvhb19x  于 2021-08-13  发布在  Java
关注(0)|答案(2)|浏览(447)
with sales as
(
select  COUNT(sale) As Number_of_sale, 
TO_CHAR(dates,'YYYY-MON') As Period

  from orders
    where dates between date '2020-03-01' and date '2020-03-31'
group by TO_CHAR(dates,'YYYY-MON') 

union all
select  COUNT(sale) As Number_of_sale,
TO_CHAR(dates,'YYYY-MON') As Period

  from orders
  where dates between date '2020-04-01' and date '2020-04-30'
group by TO_CHAR(dates,'YYYY-MON') 

)
select  Number_of_sale, period,
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 
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) '
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 
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) '
END as variances
        from sales
        order by variances asc;

我得到的输出

Number_of_sale  |  Period        |Variances
   50           |   2020-Mar         |  100%(increase)
   100          |   2020-Apr         |  Null

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

lsmepo6l

lsmepo6l1#

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

select  COUNT(sale) As Number_of_sale, 
TO_CHAR(dates,'YYYY-MON') As Period

  from orders
    where dates >= date '2019-03-01' and dates < date '2020-03-01'
group by TO_CHAR(dates,'YYYY-MON')

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

cidc1ykv

cidc1ykv2#

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

with parms  as (select trunc(date '&period_end_date','mon') dt from dual) 
   , sales as 
    ( select count(*) cnt 
           , trunc(dates,'mon') period
        from orders 
        cross join parms
       where trunc(dates,'mon') between add_months(dt, -12) 
                                         and last_day(dt)
       group by trunc(dates,'mon')
    ) 
select to_char(period, 'yyyy-Mon')  period
     , cnt                          number_of_sales 
     , to_char (round(abs(cnt - lag(cnt) over (order by period)) / cnt*100,2),'FM999999990D9999') ||
         case when cnt - lag(cnt) over (order by period) < 0 then ' %(Increase)'
              when cnt - lag(cnt) over (order by period) > 0 then ' %(Decrease)'
              else null
         end variances
  from sales  
order by variances asc;

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

相关问题