sql >> Databáze >  >> RDS >> Oracle

Sbalení datových záznamů pouze v případě, že se hodnota nezmění - Oracle SQL

Zdá se to trochu zamotané, takže bych měl zájem o vylepšení.

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
/

S těmito testovacími daty:

    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

Chápu toto:

    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

Zkoušel jsem také pomocí emp_id (4000 ), který měl tři po sobě jdoucí rozsahy dat a řešil to OK - vnější where klauzule způsobí, že mezilehlé položky v podstatě zmizí. Upraveno za účelem přidání :Nyní také funguje s vašimi dalšími obdobími pro 2000/A , protože jsem opravil řazení ve vnějším lead /lag oddíly.

Vnitřní dotaz vymaže všechna data kromě prvního počátečního a posledního koncového data pro souvislý blok a vnější dotaz používá druhé kolo lead a lag sloučit je do identických řádků, které se distinct pak se zhroutí.

Předpokládám start_date a end_date jsou DATE pole, nikoli VARCHAR2 a máte NLS_DATE_FORMAT nastavit na MMDDYYYY . Pokud jsou uloženy jako řetězce, což je špatný nápad, potřebujete to_date() na několika místech, aby řazení fungovalo správně.



  1. Django/Python:Aktualizujte vztah k bodu v nastavení.AUTH_USER_MODEL

  2. Zahodit cizí klíč, aniž byste znali název omezení?

  3. Únikové řetězce pomocí python mysql.connector

  4. postgresql malformovaný literál pole v create agregaci initcond