使用 oracle 获取过去 12 个月的计数及其差异
Posted
技术标签:
【中文标题】使用 oracle 获取过去 12 个月的计数及其差异【英文标题】:fetch last 12 months count and their variance using oracle 【发布时间】:2020-05-22 13:25:28 【问题描述】: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
我需要的输出:- 我需要过去 12 个月的数据,以及它们与上个月的差异。
【问题讨论】:
请定义方差的含义。您显然没有使用标准的统计定义。样本数据和期望的结果也会有所帮助。 Number_of_sale |期间 |方差 500 | 2020年四月 | 20%(增加(根据 2019 年 3 月的数据)) 375 | 2020-3月 | 0.2%(增加(根据 2019 年 2 月的数据)) 360 | 2020 年 2 月 |空等等... acc。到我的查询..我只获取两个月的记录,我需要过去 12 个月.. 记录 也许你应该在dates BETWEEN x AND y
里放两个多月的时间!
【参考方案1】:
首先,您需要学习使用日期作为日期,只有在极少数情况下才需要转换为字符串(最终显示结果除外)。这不是其中的一个。你所拥有的一切都可以作为日期。 这样一来,您抱怨您想要 12 个月,但您的查询只选择 2 个月。如果您想要最后 12 个,则必须选择所有 12 个。您说您想要方差,但您不是在计算统计方差,而是计算月间差异(如果 1 个月与前一个月相比有多大差异)。
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'subquery factoring'中)基本上是因为我很懒,不想多次输入参数值。但它还有一个优点,即无论输入的实际日期如何,它都会“返回”当月的 1 日。 sales cte 计算前 12 个月 (add_months(dt, -12)) 和参数日期的最后一天 (last_day(dt)) 的每个月的销售额。这些函数中的每一个都会自动调整为 2 月 29 日和不同的各个月份的天数。它获取将日期列截断为每月第一天后每个月的销售计数。 然后,主查询使用简化的情况计算月与月的差异以确定增加或减少(保持不变,但我认为它可能会被反转和/或您需要领先而不是滞后)。 免责声明:由于您实际上并未提供表定义而不是示例数据,因此未经过测试。
【讨论】:
【参考方案2】:您的查询的 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日到30日,是两个月)
【讨论】:
以上是关于使用 oracle 获取过去 12 个月的计数及其差异的主要内容,如果未能解决你的问题,请参考以下文章