oracle关于如何对不连续的开始结束时间进行合并

oracle关于如何对不连续的开始结束时间进行合并


由于工作需要,需要对一张表的数据进行开始和结束时间的拼接。比如存在以下数据。
Customer_code=‘111111‘ Sku_Code=‘ABC’ EFFECTIVE_START_DATE=‘2019-01-01’
AND EFFECTIVE_END_DATE=‘2019-04-31’
Customer_code=‘111111‘ Sku_Code=‘ABC’ EFFECTIVE_START_DATE=‘2019-03-01’
AND EFFECTIVE_END_DATE=‘2019-06-31’
Customer_code=‘111111‘ Sku_Code=‘ABC’ EFFECTIVE_START_DATE=‘2019-08-01’
AND EFFECTIVE_END_DATE=‘2019-09-31’
最后出现的开始结束时间希望是2019-01-01 --2019-06-31 2019-8-01-2019-09-31
如果是单纯的group by Customer_code,Sku_Code 然后取max, min 显然是不能实现我们的需求的.
一开始我也想不明白该如何直接对这个需求进行操作,直接对时间区间进行操作不是很好下手,甚至考虑用存储过程来操作,但是后来想到了一个好方法。
那就是首先将时间区间转化成月份,也就是上面那个例子转换成
Customer_code=‘111111‘ Sku_Code=‘ABC’ Year_month=’201901‘
Customer_code=‘111111‘ Sku_Code=‘ABC’ Year_month=’201902‘
Customer_code=‘111111‘ Sku_Code=‘ABC’ Year_month=’201903‘
Customer_code=‘111111‘ Sku_Code=‘ABC’ Year_month=’201904‘
Customer_code=‘111111‘ Sku_Code=‘ABC’ Year_month=’201905‘
Customer_code=‘111111‘ Sku_Code=‘ABC’ Year_month=’201906‘
Customer_code=‘111111‘ Sku_Code=‘ABC’ Year_month=’201908‘
Customer_code=‘111111‘ Sku_Code=‘ABC’ Year_month=’201909‘
接着将月份减去同一值200000,然后使用聚合函数,对差值进行排序,得到
Customer_code=‘111111‘ Sku_Code=‘ABC’ Year_month=’201901‘ LX=1901 1
Customer_code=‘111111‘ Sku_Code=‘ABC’ Year_month=’201902‘ LX=1902 2
Customer_code=‘111111‘ Sku_Code=‘ABC’ Year_month=’201903‘ LX=1903 3
Customer_code=‘111111‘ Sku_Code=‘ABC’ Year_month=’201904‘ LX=1904 4
Customer_code=‘111111‘ Sku_Code=‘ABC’ Year_month=’201905‘ LX=1905 5
Customer_code=‘111111‘ Sku_Code=‘ABC’ Year_month=’201906‘ LX=1906 6
Customer_code=‘111111‘ Sku_Code=‘ABC’ Year_month=’201908‘ LX=1908 7
Customer_code=‘111111‘ Sku_Code=‘ABC’ Year_month=’201909‘ LX=1909 8
接着,将LX减去排序后得到的序号,得到
Customer_code=‘111111‘ Sku_Code=‘ABC’ Year_month=’201901‘ PX=1900
Customer_code=‘111111‘ Sku_Code=‘ABC’ Year_month=’201902‘ PX=1900
Customer_code=‘111111‘ Sku_Code=‘ABC’ Year_month=’201903‘ PX=1900
Customer_code=‘111111‘ Sku_Code=‘ABC’ Year_month=’201904‘ PX=1900
Customer_code=‘111111‘ Sku_Code=‘ABC’ Year_month=’201905‘ PX=1900
Customer_code=‘111111‘ Sku_Code=‘ABC’ Year_month=’201906‘ PX=1900
Customer_code=‘111111‘ Sku_Code=‘ABC’ Year_month=’201908‘ PX=1901
Customer_code=‘111111‘ Sku_Code=‘ABC’ Year_month=’201909‘ PX=1901
可以发现,如果是连续月份,那么PK的值是相同的。
那么接下来一切就简单了,group by CUSTOMER_CODE,SKU_CODE,PX 然后取最小月为开始月份,取最大月为结束月份。
最后根据要求,将月份转换成’yyyy-MM-dd‘格式即可。
以下是相关代码

–首先通过行转列将时间区间化作月份
with tab as(
select DISTINCT CUSTOMER_CODE,SKU_CODE,
start_date + level - 1 YEAR_MONTH
from (
select rownum rn, CUSTOMER_CODE,SKU_CODE, TO_CHAR(EFFECTIVE_START_DATE, ‘YYYYMM’) start_date,
TO_CHAR(EFFECTIVE_END_DATE, ‘YYYYMM’) end_date
from (SELECT DISTINCT A.CUSTOMER_CODE,A.SKU_CODE,A.EFFECTIVE_START_DATE,
DECODE(A.EFFECTIVE_END_DATE,DATE’9999-12-31’,ADD_MONTHS(SYSDATE,12),A.EFFECTIVE_END_DATE) EFFECTIVE_END_DATE
FROM DW_DMS_D_TERRITORY_AL_TG A
WHERE TO_CHAR(NVL(A.EFFECTIVE_END_DATE,DATE’9999-12-31’),‘YYYY’) >= ‘2019’
)
)
connect by level <= end_date - start_date + 1
and prior rn = rn
and prior dbms_random.value is not null
),
tab2 as(
select * from tab
where substr(YEAR_MONTH,-2)<=12 AND substr(YEAR_MONTH,-2)<>‘00’
)
,
tab3 as(
select tab2.*,YEAR_MONTH-200000 LX
from tab2 )
,
TAB4 as(
select CUSTOMER_CODE,SKU_CODE,YEAR_MONTH,LX,ROW_NUMBER() OVER(PARTITION BY CUSTOMER_CODE,SKU_CODE ORDER BY LX)-LX PX
from TAB3
)
select CUSTOMER_CODE,SKU_CODE,
MIN(TO_DATE(YEAR_MONTH,‘yyyy-MM’)) EFFECTIVE_START_DATE,
LAST_DAY(DECODE(MAX(TO_DATE(YEAR_MONTH,‘yyyy-MM’)),TRUNC(ADD_MONTHS(SYSDATE,12),‘MM’),
DATE’9999-12-31’,MAX(TO_DATE(YEAR_MONTH,‘yyyy-MM’)))) EFFECTIVE_END_DATE
from TAB4
group by CUSTOMER_CODE,SKU_CODE,PX

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值