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

Cara menghasilkan baris untuk rentang tanggal dengan kunci

di 10g/11g Anda dapat menggunakan klausa model untuk ini.

SQL> with emps as (select rownum id, name, start_date,
  2                       end_date, trunc(end_date)-trunc(start_date) date_range
  3                  from table1)
  4  select name, the_date
  5    from emps
  6  model partition by(id as key)
  7        dimension by(0 as f)
  8        measures(name, start_date, cast(null as date) the_date, date_range)
  9        rules (the_date [for f from 0 to date_range[0] increment 1]  = start_date[0] + cv(f),
 10               name[any] = name[0]);

NAME        THE_DATE
----------- ----------
DAVID SMITH 01-01-2001
DAVID SMITH 01-02-2001
DAVID SMITH 01-03-2001
DAVID SMITH 01-04-2001
DAVID SMITH 01-05-2001
DAVID SMITH 01-06-2001
JOHN SMITH  02-07-2012
JOHN SMITH  02-08-2012
JOHN SMITH  02-09-2012

9 rows selected.

yaitu kueri dasar Anda:

select rownum id, name, start_date,
       end_date, trunc(end_date)-trunc(start_date) date_range
  from table1

cukup tentukan tanggal + rentangnya (saya menggunakan id rownum, tetapi jika Anda memiliki PK, Anda dapat menggunakannya sebagai gantinya.

partisi membagi perhitungan kita per ID(baris unik):

6  model partition by(id as key)

langkah-langkahnya:

8        measures(name, start_date, cast(null as date) the_date, date_range)

mendefinisikan atribut yang akan kita hasilkan/hitung. dalam hal ini, kami bekerja dengan nama, dan tanggal_mulai ditambah rentang baris yang akan dihasilkan. selain itu saya telah menetapkan kolom the_date yang akan menampung tanggal yang dihitung (yaitu kami ingin menghitung tanggal_mulai + n di mana n adalah dari 0 hingga rentang.

aturan menentukan BAGAIMANA kita akan mengisi kolom kita:

9        rules (the_date [for f from 0 to date_range[0] increment 1]  = start_date[0] + cv(f),
10               name[any] = name[0]);

begitu juga dengan 

the_date [for f from 0 to date_range[0] increment 1]

kami mengatakan bahwa kami akan menghasilkan jumlah baris yang memiliki rentang_tanggal+1 (yaitu total 6 tanggal). nilai f dapat dirujuk melalui cv (nilai saat ini) fungsi.

jadi pada baris 1 untuk david, kita akan memiliki the_date [0] = start_date+0 dan selanjutnya pada baris 2, kita akan memiliki the_date [1] = start_date+1 . sepanjang jalan hingga start_date+5 (yaitu end_date )

p.s.untuk terhubung dengan Anda harus melakukan sesuatu seperti ini:

select 
    A.EMPLOYEE_NAME,
    A.START_DATE+(b.r-1) AS INDIVIDUAL_DAY,
    TO_CHAR(A.START_DATE,'MM/DD/YYYY') START_DATE,
    TO_CHAR(A.END_DATE,'MM/DD/YYYY') END_DATE
FROM table1 A
     cross join (select rownum r
                   from (select max(end_date-start_date) d from table1)
                  connect by level-1 <= d) b
 where A.START_DATE+(b.r-1) <= A.END_DATE
 order by 1, 2;

yaitu mengisolasi koneksi dengan subkueri, lalu memfilter baris di mana hari_individu> tanggal_akhir.

tetapi saya TIDAK AKAN merekomendasikan pendekatan ini. kinerjanya akan lebih buruk dibandingkan dengan pendekatan model (terutama jika rentangnya besar).



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Cara menjalankan Opatch dalam bentuk non-interaktif

  2. Daftar Tanggal + Jam antara dua tanggal

  3. Variabel Oracle 11g Bind tidak ada

  4. Sinkronisasi prosedur PL/SQL. Bagaimana menjamin pelaksanaan prosedur hanya satu kali?

  5. Bisakah saya memiliki banyak database di edisi oracle express?