Oracle
 sql >> Datenbank >  >> RDS >> Oracle

Reduzieren von Datumsdatensätzen nur, wenn sich der Wert nicht ändert - Oracle SQL

Das scheint ein bisschen verworren, also wäre ich an Verbesserungen interessiert.

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
/

Mit diesen Testdaten:

    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

Ich verstehe:

    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

Ich habe es auch mit einer emp_id versucht (4000 ), die drei zusammenhängende Datumsbereiche hatte, und es hat damit gut umgegangen - das äußere where -Klausel lässt die Zwischeneinträge im Wesentlichen verschwinden. Bearbeitet, um hinzuzufügen :Funktioniert jetzt auch mit Ihren zusätzlichen Datumsbereichen für 2000/A , da ich die Reihenfolge im äußeren lead festgelegt habe /lag Partitionen.

Die innere Abfrage blendet alles außer dem ersten Startdatum und dem letzten Enddatum für einen zusammenhängenden Block aus, und die äußere Abfrage verwendet eine zweite Runde von lead und lag um sie zu identischen Zeilen zusammenzuführen, was der distinct bricht dann zusammen.

Ich nehme start_date an und end_date sind DATE Felder, nicht VARCHAR2 , und Sie haben NLS_DATE_FORMAT auf MMDDYYYY gesetzt . Wenn sie als Strings gespeichert werden, was keine gute Idee ist, brauchen Sie to_date() an einigen Stellen, damit die Bestellung richtig funktioniert.



No