Oracle
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Oracle

MySQL thay thế cho hàm NEXT_DAY của Oracle là gì?

Tôi sẽ ngả mũ bái phục bằng một cách tiếp cận khác:

Chỉnh sửa: Tôi nhận ra hơi muộn màng rằng hàm Oracle được đề cập lấy một chuỗi làm đối số thứ hai và vì vậy điều này không phù hợp chính xác với yêu cầu. Tuy nhiên MySQL đã vui lòng xác định 0 - 6 là Thứ Hai - Chủ Nhật, và dù sao thì tôi cũng phản đối về mặt đạo đức đối với việc sử dụng một chuỗi làm đối số cho loại điều này. Một chuỗi sẽ đến từ đầu vào của người dùng hoặc một ánh xạ khác trong mã cấp cao hơn giữa các giá trị số và chuỗi. Tại sao không chuyển một số nguyên? :)

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

Để chia nhỏ phần xác định INTERVAL giá trị:

Phần đầu tiên của phương trình chỉ đơn giản là lấy phần bù giữa ngày trong tuần được chỉ định và ngày trong tuần của ngày được chỉ định:

p_weekday - WEEKDAY(p_date)

Điều này sẽ trả về một số dương nếu p_weekday lớn hơn WEEKDAY(p_date) và ngược lại. Số 0 sẽ được trả lại nếu chúng giống nhau.

ROUND() phân đoạn được sử dụng để xác định xem ngày được yêu cầu trong tuần (p_weekday ) đã xảy ra trong tuần hiện tại so với ngày (p_date ) được chỉ định. Vì vậy, bằng ví dụ ...

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

..returns 0 , cho biết Chủ nhật đó (6 ) đã không xảy ra trong tuần này, vì 2019-01-25 là một ngày thứ sáu. Tương tự như vậy ...

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

... trả về 1 bởi vì Thứ Tư (2 ) đã trôi qua. Lưu ý rằng điều này sẽ trả về 0 nếu p_weekday giống như ngày trong tuần của p_date .

Giá trị này (1 hoặc 0 ) sau đó được nhân với hằng số 7 (số ngày trong tuần).

Do đó nếu p_weekday đã xảy ra trong tuần hiện tại, nó sẽ thêm 7 vào bù đắp p_weekday - WEEKDAY(p_date) , bởi vì phần bù đó sẽ là một số âm và chúng tôi muốn có một ngày trong tương lai.

Nếu p_weekday vẫn chưa xảy ra trong tuần hiện tại, khi đó chúng ta chỉ có thể thêm phần bù vào ngày hiện tại vì phần bù sẽ là một số dương. Do đó, phần ROUND(...) * 7 bằng 0 và về bản chất, bị bỏ qua.

Mong muốn của tôi đối với phương pháp này là mô phỏng một IF() điều kiện về mặt toán học. Điều này sẽ hợp lệ như nhau:

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

Và vì tính khách quan, khi chạy 1 triệu lần lặp một vài lần của mỗi hàm, IF phiên bản dựa trên trung bình nhanh hơn khoảng 4,2% so với ROUND phiên bản dựa trên.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Truy vấn SQL để dịch một danh sách các số được so khớp với một số phạm vi, thành một danh sách các giá trị

  2. Nhóm SQL theo ngày (giờ)

  3. Cập nhật với sau khi chèn trình kích hoạt trên cùng một bảng

  4. Lệnh gọi ODP.NET của Thư viện Doanh nghiệp trả về ORA-06502:PL / SQL:lỗi số hoặc giá trị

  5. Oracle:Nếu bảng tồn tại