Oracle
 sql >> база данни >  >> RDS >> Oracle

Свиване на записи за дати само ако стойността не се променя - Oracle SQL

Това изглежда малко заплетено, така че ще се интересувам от подобрения.

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 (4000 ), който имаше три последователни диапазона от дати и се справи с това ОК - външния where клауза кара междинните записи да изчезнат по същество. Редактирано за добавяне :Вече работи и с вашите допълнителни периоди от време за 2000/A , тъй като поправих подреждането във външния lead /lag дялове.

Вътрешната заявка заличава всичко освен първата начална дата и последната крайна дата за съседен блок, а външната заявка използва втори кръг от lead и lag за да ги обедините в идентични редове, които са distinct след което се свива.

Предполагам start_date и end_date са DATE полета, а не VARCHAR2 и имате NLS_DATE_FORMAT зададен на MMDDYYYY . Ако се съхраняват като низове, което е лоша идея, имате нужда от to_date() на доста места, за да може подреждането да работи правилно.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Не може да се направи пакетно вмъкване в Oracle DB с помощта на MyBatis

  2. Прозоречната функция Last_value не работи правилно

  3. Как да премахна стойността по подразбиране от колона в oracle?

  4. Как Java за OS X 2013-004 засяга (прекъсва) Swing приложения?

  5. Позволено ли е използването на SELECT в конвейерна PL/SQL таблична функция?