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

Apa alternatif MySQL untuk fungsi NEXT_DAY Oracle?

Saya akan melempar topi saya ke atas ring dengan pendekatan lain:

Sunting: Saya agak terlambat menyadari bahwa fungsi Oracle yang dimaksud mengambil string sebagai argumen kedua, jadi ini tidak sesuai dengan persyaratan. Namun MySQL telah dengan ramah mendefinisikan 0 - 6 sebagai Senin - Minggu, dan bagaimanapun saya memiliki keberatan moral untuk menggunakan string sebagai argumen untuk hal semacam ini. String akan berasal dari input pengguna atau pemetaan lain dalam kode tingkat yang lebih tinggi antara nilai numerik dan string. Mengapa tidak lulus bilangan bulat? :)

CREATE FUNCTION `fnDayOfWeekGetNext`(
        p_date DATE,
        p_weekday TINYINT(3)
        ) RETURNS date
BEGIN

        RETURN DATE_ADD(p_date, INTERVAL p_weekday - WEEKDAY(p_date) + (ROUND(WEEKDAY(p_date) / (p_weekday + WEEKDAY(p_date) + 1)) * 7) DAY);

END

Untuk memecah bagian yang menentukan INTERVAL nilai:

Bagian pertama persamaan hanya mendapatkan offset antara hari kerja yang ditentukan dan hari kerja dari tanggal yang ditentukan:

p_weekday - WEEKDAY(p_date)

Ini akan mengembalikan angka positif jika p_weekday lebih besar dari WEEKDAY(p_date) dan sebaliknya. Nol akan dikembalikan jika sama.

ROUND() segmen digunakan untuk menentukan apakah hari yang diminta dalam seminggu (p_weekday ) telah terjadi dalam minggu ini relatif terhadap tanggal (p_date ) ditentukan. Jadi, dengan contoh...

ROUND(WEEKDAY('2019-01-25') / (6 + WEEKDAY('2019-01-25') + 1))

..mengembalikan 0 , menunjukkan bahwa hari Minggu (6 ) belum terjadi minggu ini, karena 2019-01-25 adalah hari Jumat. Demikian juga...

ROUND(WEEKDAY('2019-01-25') / (2 + WEEKDAY('2019-01-25') + 1))

...mengembalikan 1 karena hari Rabu (2 ) telah berlalu. Perhatikan bahwa ini akan mengembalikan 0 jika p_weekday sama dengan hari kerja p_date .

Nilai ini (baik 1 atau 0 ) kemudian dikalikan dengan konstanta 7 (jumlah hari dalam seminggu).

Oleh karena itu jika p_weekday telah terjadi dalam minggu ini, itu akan menambahkan 7 ke offset p_weekday - WEEKDAY(p_date) , karena offset itu akan menjadi angka negatif dan kami ingin tanggal di masa mendatang.

Jika p_weekday belum terjadi di minggu ini, maka kita bisa menambahkan offset ke tanggal saat ini karena offset akan menjadi angka positif. Oleh karena itu bagian ROUND(...) * 7 sama dengan nol dan, pada dasarnya, diabaikan.

Keinginan saya untuk pendekatan ini adalah untuk mensimulasikan IF() kondisi secara matematis. Ini akan sama validnya:

RETURN DATE_ADD(p_date, INTERVAL p_weekday - WEEKDAY(p_date) + IF(p_weekday - WEEKDAY(p_date) < 0, 7, 0) DAY);

Dan untuk kepentingan objektivitas, dalam menjalankan 1 juta iterasi beberapa kali setiap fungsi IF -versi berbasis rata-rata sekitar 4,2% lebih cepat daripada ROUND versi berbasis.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. penyisipan beberapa baris di Oracle SQL

  2. Menggunakan `SELECT` untuk memanggil fungsi

  3. Mengambil informasi tipe data untuk kolom di Oracle OCCI ResultSet

  4. GALAT:Referensikan penghitung sebagai target tugas - PL/SQL

  5. Penguraian XML di Oracle pl/sql