sql >> Database >  >> RDS >> Oracle

Datumrecords alleen samenvouwen als de waarde niet verandert - Oracle SQL

Dit lijkt een beetje ingewikkeld, dus ik ben geïnteresseerd in verbeteringen.

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
/

Met deze testgegevens:

    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

Ik krijg dit:

    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

Ik heb het ook geprobeerd met een emp_id (4000 ) die drie aaneengesloten datumbereiken had, en het behandelde dat OK - de buitenste where clausule zorgt ervoor dat de tussenliggende vermeldingen in wezen verdwijnen. Bewerkt om toe te voegen :Werkt nu ook met uw aanvullende datumbereiken voor 2000/A , aangezien ik de volgorde in de buitenste lead heb aangepast /lag partities.

De binnenste query maakt alles leeg behalve de eerste startdatum en laatste einddatum voor een aaneengesloten blok, en de buitenste query gebruikt een tweede ronde van lead en lag om ze samen te voegen tot identieke rijen, die de distinct stort dan in.

Ik neem aan start_date en end_date zijn DATE velden, niet VARCHAR2 , en je hebt NLS_DATE_FORMAT ingesteld op MMDDYYYY . Als ze worden opgeslagen als strings, wat een slecht idee is, heb je to_date() . nodig op nogal wat plaatsen om het bestellen goed te laten werken.



  1. Oracle + Oci8 + php5.6 + Ubuntu 16.04

  2. Langzame volgorde van zoekopdrachten door een kolom in een samengevoegde tabel

  3. Hoe twee DATE-waarden te vergelijken die alleen zijn gebaseerd op het datumgedeelte in Oracle?

  4. Geef variabele waarde door van JS naar PHP