【知识分享】ORACLE函数分享_作者(刘鹤)
最近看到了几个ORACLE函数,感觉挺好用的,且可应用于我们的工作中,尤其针对采集,可能会有些用处,所以分享下。仅供参考,谢谢
1、 lag&lead函数:利用lag和lead函数,我们可以在同一行中显示前n行的数据,也可以显示后n行的数据
应用场景:采集或者报表需求要求同时展示本月指标、上月指标做比较等。一般情况下我们会写两个iqd或者用表自己和自己做外关联实现。此时可通过lag函数实现。
参考代码如下,通过一段代码获取缴费日当日、昨日、前日、明日、后日保费等。
select t.PAYMENT_DATE,
t.TOT_MODAL_PREM as cur_prem,--今日保费
lag(t.TOT_MODAL_PREM, 2, 0) over(order by t.PAYMENT_DATE) as pre_pre_prem,--前两天的保费
lag(t.TOT_MODAL_PREM, 1, 0) over(order by t.PAYMENT_DATE) as pre_prem,--昨日保费的保费
lead(t.TOT_MODAL_PREM, 2, 0) over(order by t.PAYMENT_DATE) as next_next_prem,--后两天的保费
lead(t.TOT_MODAL_PREM, 1, 0) over(order by t.PAYMENT_DATE) as next_prem--明天保费
from (select T2.DATEVALUE AS PAYMENT_DATE,
NVL(T3.TOT_MODAL_PREM, 0) AS TOT_MODAL_PREM
from LBS_WORKDAY T2,
(select /*+INDEX(T1 IX_LBSPREMINFO_PAYMENTDATE)*/
trunc(t1.PAYMENT_DATE, ‘dd‘) as PAYMENT_DATE,
NVL(sum(t1.TOT_MODAL_PREM), 0) as TOT_MODAL_PREM
from lbs_prem_info t1
where T1.PAYMENT_DATE >= to_date(20100101, ‘yyyymmdd‘)
group by trunc(t1.PAYMENT_DATE, ‘dd‘)) t3
WHERE T2.DATEVALUE = T3.PAYMENT_DATE(+)
AND T2.DATEVALUE >= to_date(20100101, ‘yyyymmdd‘)) T
注意:
Ø lag&lead函数的目的是获取返回数据的此条记录前n行和后n行记录,为保证逻辑无误,一定要处理好排序字段。
Ø 同时,上述代码中我用LBS_WORKDAY做了一次外关联,原因是我不能保证每日都有保费,所以事先通过LBS_WORKDAY表虚拟出每日的数据,以保证我获取的前n条和后n条记录确实是前n日和后n日的记录
2、 Cube:group by cube(a,b)的功能就是在原有的group by a,b 的汇总力度下增加了根据a进一步汇总的记录和根据b进一步汇总的记录,
应用场景:要求汇总字段或者力度不同的采集。如要求分别根据应缴时间和实收时间做汇总的保费,一般我们写两个group by语句,此时可通过cube实现
参考代码如下:
select /*+INDEX(T1 IX_LBSPREMINFO_PAYMENTDATE)*/
DECODE(GROUPING(trunc(t1.PAYMENT_DATE, ‘MM‘)),
1,
‘ALL_PMD‘,--应缴月保费
TO_CHAR(trunc(t1.PAYMENT_DATE, ‘MM‘), ‘YYYYMM‘)) as PAYMENT_DATE,
DECODE(GROUPING(trunc(T1.PAY_TO_DATE, ‘MM‘)),
1,
‘ALL_PTD‘,--缴费月保费
TO_CHAR(trunc(t1.PAY_TO_DATE, ‘MM‘), ‘YYYYMM‘)) AS PAY_TO_DATE,
sum(t1.TOT_MODAL_PREM) as TOT_MODAL_PREM
from lbs_prem_info t1
where T1.PAYMENT_DATE >= to_date(20100101, ‘yyyymmdd‘)
OR T1.PAY_TO_DATE >= to_date(20100101, ‘yyyymmdd‘)
group by cube(trunc(t1.PAYMENT_DATE, ‘MM‘), trunc(T1.PAY_TO_DATE, ‘MM‘))
解释:
Ø Grouping函数的目的:上述cube中新增的根据AorB汇总的记录会产生null字段,如,根据A汇总,则B字段展示null,此时grouping函数会将 null值赋值为1。如此可容易提取统计所需数据
Ø 上述代码可返回四种结果:A、满足(PAYMENT_DATE=‘ALL_PMD‘ and PAY_TO_DATE=‘ALL_PTD‘),则返回结果为全部汇总数据,相当于无group by 的最大汇总力度;B、满足(PAYMENT_DATE=‘ALL_PMD‘ and PAY_TO_DATE<>‘ALL_PTD‘),则返回结果为应缴月的保费;C、满足(PAYMENT_DATEM<>‘ALL_PMD‘ and PAY_TO_DATE=‘ALL_PTD‘)则为缴费月的保费;D、满足((PAYMENT_DATEM<>‘ALL_PMD‘ and PAY_TO_DATE<>‘ALL_PTD‘)),则返回结果相当于group by trunc(t1.PAYMENT_DATE, ‘MM‘), trunc(T1.PAY_TO_DATE, ‘MM‘)的结果
3、 ratio_to_report& first_value&last_value:其中ratio_to_report可获取不同汇总力度的占比值;first_value&last_value可获取根据某种情况分组排序后最好或者最坏的字段值。
应用场景:采集需求或者报表需求获取各维度占比等需求以及可获取时间最早、最晚或者业绩最好、最坏的维度等。一般情况下我们会通过多段代码实现,此时,可通过上述函数一次性实现
参考代码如下:
select trunc(t.payment_date, ‘dd‘),
t.plan_code,
sum(t.tot_modal_prem), --每日分险种保费
sum(sum(t.tot_modal_prem)) over(partition by trunc(t.payment_date, ‘dd‘)), --每日保费
ratio_to_report(sum(t.tot_modal_prem)) over(partition by trunc(t.payment_date, ‘dd‘)), --每日分险种保费占比
first_value(t.plan_code) over(partition by trunc(t.payment_date, ‘dd‘) order by sum(t.tot_modal_prem) desc rows unbounded preceding) as best_plan, --每日业绩最好的险种
first_value(t.plan_code) over(partition by trunc(t.payment_date, ‘dd‘) order by sum(t.tot_modal_prem) asc rows unbounded preceding) as worst_plan --每日业绩最差的险种
from lbs_prem_info t
group by trunc(t.payment_date, ‘dd‘), t.plan_code