これは少し複雑に思えるので、改善に興味があります。
select distinct emp_id,
nvl(x_start_date,
lag(x_start_date)
over (partition by emp_id
order by rn)) as start_date,
nvl(x_end_date,
lead(x_end_date)
over (partition by emp_id
order by rn nulls first))
as end_date,
rating,
department
from (
select emp_id, start_date, end_date, rating, department,
case start_date
when lag(end_date)
over (partition by emp_id, rating, department
order by start_date) then null
else start_date end as x_start_date,
case end_date
when lead(start_date)
over (partition by emp_id, rating, department
order by start_date) then null
else end_date end as x_end_date,
rownum as rn
from table1
)
where x_start_date is not null or x_end_date is not null
order by emp_id, start_date
/
このテストデータを使用して:
EMP_ID START_DA END_DATE RA DEPARTMENT SALARY
---------- -------- -------- -- -------------------- ----------
2000 01012010 01012011 A HR 9000
2000 01012011 01012012 A HR 10000
2000 01012012 01012013 A+ HR 20000
2000 01012013 01012014 A HR 20000
2000 01012014 12319999 A HR 21000
3000 01012011 01012012 B Operations 50000
3000 01012012 12319999 B Operations 60000
4000 07012011 07012012 B Operations 50000
4000 07012012 07012013 B Operations 50000
4000 07012013 12319999 B Operations 60000
私はこれを手に入れます:
EMP_ID START_DA END_DATE RA DEPARTMENT
---------- -------- -------- -- --------------------
2000 01012010 01012012 A HR
2000 01012012 01012013 A+ HR
2000 01012013 12319999 A HR
3000 01012011 12319999 B Operations
4000 07012011 12319999 B Operations
emp_id
また、3つの連続した日付範囲を持つ( )を試してみました4000
が、それで問題ありませんでした。外側のwhere
句を使用すると、基本的に中間エントリが表示されなくなります。追加のために編集:外部/パーティション2000/A
の順序を修正したため、の追加の日付範囲でも機能するようになりました。lead
lag
内側のクエリは、連続するブロックの最初の開始日と最後の終了日を除くすべてを空白にし、外側のクエリは、の2回目のラウンドを使用して、lead
それらlag
を同じ行にマージしますdistinct
。
私は、start_date
とend_date
はDATE
フィールドではなくVARCHAR2
、フィールドであると想定しています。あなたはにNLS_DATE_FORMAT
設定しましたMMDDYYYY
。それらが文字列として保存されている場合、これは悪い考えですがto_date()
、順序付けを正しく機能させるには、かなりの数の場所が必要です。