oracle關於如何對不連續的開始結束時間進行合併

2021-09-25 19:27:20 字數 4031 閱讀 3921

由於工作需要,需要對一張表的資料進行開始和結束時間的拼接。比如存在以下資料。

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

如何查詢不連續的id值

如何查詢不連續的id值 表t有乙個id列,自增型別,用sql如何找出不連續的資料呢?如 t表id列有如下資料,1 2 3 5 6 8 如何找出不連續的資料 4 7 解決方案 select rownum from dual connect by rownum select max id from t ...

Oracle不連續的值,如何實現查詢上一條 下一條

檢視得知,資料庫中用於查詢的字段 主鍵 是不連續的。如上圖所示 stxh為主鍵number型別。下一條 select nowid,afterid from select stxh nowid,lead stxh,1 over order by stxh as afterid from exm kst...

Oracle不連續的值,如何實現查詢上一條 下一條

檢視得知,資料庫中用於查詢的字段 主鍵 是不連續的。如上圖所示 stxh為主鍵number型別。下一條 select nowid,afterid from select stxh nowid,lead stxh,1 over order by stxh as afterid from exm kst...