Oracle
 sql >> Teknologi Basis Data >  >> RDS >> Oracle

Menciutkan catatan tanggal hanya jika nilainya tidak berubah - Oracle SQL

Ini tampaknya agak berbelit-belit, jadi saya tertarik untuk meningkatkannya.

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
/

Dengan data uji ini:

    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

Saya mengerti ini:

    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

Saya juga mencoba dengan emp_id (4000 ) yang memiliki tiga rentang tanggal yang bersebelahan, dan itu menangani OK - where luar klausa membuat entri perantara menghilang, pada dasarnya. Diedit untuk ditambahkan :Juga sekarang berfungsi dengan rentang tanggal tambahan Anda untuk 2000/A , karena saya memperbaiki pemesanan di lead outer luar /lag partisi.

Kueri dalam mengosongkan semua kecuali tanggal mulai pertama dan tanggal akhir terakhir untuk blok yang berdekatan, dan kueri luar menggunakan putaran kedua lead dan lag untuk menggabungkannya menjadi baris yang identik, yang distinct lalu ambruk.

Saya berasumsi start_date dan end_date adalah DATE bidang, bukan VARCHAR2 , dan Anda memiliki NLS_DATE_FORMAT setel ke MMDDYYYY . Jika disimpan sebagai string, yang merupakan ide yang buruk, Anda memerlukan to_date() di beberapa tempat agar pemesanan berfungsi dengan baik.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Bagaimana cara menambahkan batasan di Oracle SQL untuk membatasi nilai?

  2. ORACLE - temukan hasil nyata di dalam LOOP (ATAU SERUPA)

  3. Bagaimana menemukan kolom yang digunakan dalam kueri dinamis tanpa menjalankan seluruh kueri

  4. Perhitungan Biaya Rata-Rata Inventaris dalam SQL

  5. Agregasi string Oracle