sql >> Databasteknik >  >> RDS >> Oracle

Komprimerar datumposter endast om värdet inte ändras - Oracle SQL

Det här verkar lite invecklat, så jag skulle vara intresserad av förbättringar.

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
/

Med dessa testdata:

    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

Jag förstår detta:

    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

Jag försökte också med en emp_id (4000 ) som hade tre sammanhängande datumintervall, och det hanterade det OK - den yttre where klausul gör att mellanposterna försvinner i huvudsak. Redigerad för att lägga till :Fungerar nu även med dina ytterligare datumintervall för 2000/A , eftersom jag fixade beställningen i den yttre lead /lag partitioner.

Den inre frågan tömmer ut alla utom det första startdatumet och sista slutdatumet för ett sammanhängande block, och den yttre frågan använder en andra omgång av lead och lag för att slå samman dem till identiska rader, som är distinct kollapsar sedan.

Jag antar start_date och end_date är DATE fält, inte VARCHAR2 , och du har NLS_DATE_FORMAT inställd på MMDDYYYY . Om de lagras som strängar, vilket är en dålig idé, behöver du to_date() på ganska många ställen för att få beställningen att fungera korrekt.



  1. Kör Oracle SQL-skript med Ansible playbook

  2. Felkod:1305. FUNKTION eller PROCEDUR finns inte

  3. Undantagshantering i Procedur med kapslade funktioner i pl/sql

  4. MySQL 5.1 till 5.7 ändra order Genom att inte längre fungera