0

OracleSQLで以下の問題を解決するためにあなたの助けが必要です。

表1(入力)

 Emp_ID Start_Date  End_Date    Rating  Department  Salary
2000    01012011    01012012    A   HR          10000
2000    01012012    01012013    A+  HR          20000
2000    01012013    12319999    A   HR          20000
3000    01012011    01012012    B   Operations  50000
3000    01012012    12319999    B   Operations  60000

表2(出力)

 Emp_ID Start_Date  End_Date    Rating  Department
2000    01012011    12312011    A   HR
2000    01012012    12312012    A+  HR
2000    01012013    12319999    A   HR
3000    01012011    12319999    B   Operations

日付レコードを折りたたむのは、従業員の評価が次の連続する日付範囲で同じであり、評価が変更されるまで継続する必要がある場合のみです。

質問を明確にしたいと思います。

私は他の答えを見て、関数をリードしてラグする必要があると考えました。しかし、誰かが開始方法に光を当てることができれば、それは素晴らしいことです。

ありがとう

4

2 に答える 2

1
select *
from inputtable it1
left join inputtable it2 
       on it1.emp_id = it2.emp_id
      and it1.rating = it2.rating
      and it1.start_date < it2.start_date
      and not exists(select * from inputtable it2a
                     where it1.emp_id = it2a.emp_id
                       and ((it1.rating <> it2a.rating
                         and it1.start_date < it2a.start_date
                         and it2.start_date > it2a.start_date)
                         or (it1.rating = it2a.rating
                         and exists(select * from inputtable it2b
                                    where it2a.emp_id = it2b.emp_id
                                      and it2a.rating = it2b.rating
                                      and it2a.end_date + 1 = it2b.start_date))))
where not exists(select * from inputtable it1a
                 where it1.emp_id = it1a.emp_id
                   and it1.rating = it1a.rating
                   and it1.start_date = it1a.end_date + 1)
于 2012-07-06T04:18:51.733 に答える
1

これは少し複雑に思えるので、改善に興味があります。

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の順序を修正したため、の追加の日付範囲でも機能するようになりました。leadlag

内側のクエリは、連続するブロックの最初の開始日と最後の終了日を除くすべてを空白にし、外側のクエリは、の2回目のラウンドを使用して、leadそれらlagを同じ行にマージしますdistinct

私は、start_dateend_dateDATEフィールドではなくVARCHAR2、フィールドであると想定しています。あなたはにNLS_DATE_FORMAT設定しましたMMDDYYYY。それらが文字列として保存されている場合、これは悪い考えですがto_date()、順序付けを正しく機能させるには、かなりの数の場所が必要です。

于 2012-07-06T14:36:38.660 に答える