Oracle
 sql >> Baza danych >  >> RDS >> Oracle

Jaka jest alternatywa MySQL dla funkcji NEXT_DAY Oracle?

Wrzucę kapelusz na ring z jeszcze innym podejściem:

Edytuj: Z pewnym opóźnieniem zdaję sobie sprawę, że funkcja Oracle, o której mowa, jako drugi argument przyjmuje ciąg znaków, więc nie spełnia to dokładnie wymagań. Jednak MySQL uprzejmie zdefiniował już 0 - 6 jako poniedziałek - niedziela, a poza tym mam moralne zastrzeżenia do używania łańcucha jako argumentu dla tego typu rzeczy. Ciąg znaków pochodziłby z danych wejściowych użytkownika lub jeszcze jedno mapowanie w kodzie wyższego poziomu między wartościami liczbowymi i łańcuchowymi. Dlaczego nie przekazać liczby całkowitej? :)

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

Aby podzielić część określającą INTERVAL wartość:

Pierwsza część równania po prostu pobiera przesunięcie między podanym dniem tygodnia a dniem tygodnia podanej daty:

p_weekday - WEEKDAY(p_date)

Zwróci to liczbę dodatnią, jeśli p_weekday jest większe niż WEEKDAY(p_date) i wzajemnie. Zero zostanie zwrócone, jeśli będą takie same.

ROUND() segment służy do określenia, czy żądany dzień tygodnia (p_weekday ) wystąpił już w bieżącym tygodniu w stosunku do daty (p_date ) określone. Na przykład...

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

..zwraca 0 , wskazując, że niedziela (6 ) nie miało miejsca w tym tygodniu, ponieważ 2019-01-25 jest piątek. Podobnie...

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

...zwraca 1 ponieważ środa (2 ) już minął. Zauważ, że to zwróci 0 jeśli p_weekday jest taki sam jak dzień tygodnia p_date .

Ta wartość (albo 1 lub 0 ) jest następnie mnożona przez stałą 7 (liczba dni w tygodniu).

Dlatego jeśli p_weekday już wystąpił w bieżącym tygodniu, doda 7 do przesunięcia p_weekday - WEEKDAY(p_date) , ponieważ przesunięcie byłoby liczbą ujemną i chcemy mieć datę w przyszłości.

Jeśli p_weekday jeszcze nie wystąpił w bieżącym tygodniu, możemy po prostu dodać przesunięcie do bieżącej daty, ponieważ przesunięcie będzie liczbą dodatnią. Stąd sekcja ROUND(...) * 7 jest równy zero i zasadniczo jest ignorowany.

Moim pragnieniem tego podejścia było symulowanie IF() warunek matematycznie. Byłoby to równie ważne:

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

A w interesie obiektywizmu, uruchamiając 1M iteracji kilka razy dla każdej funkcji, IF wersja oparta średnio o 4,2% szybciej niż ROUND wersja oparta.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Film:Wydajność kolumny Oracle 12c IDENTITY w systemie RAC

  2. Wpływ EM SQL Monitor

  3. Jak napisać skrypt wstawiania oracle z jednym polem jako CLOB?

  4. Ograniczenie unikatowe Oracle SQL A do B, B do A

  5. Wyrażenie regularne Oracle zawierające myślnik nie daje takiego samego wyniku w systemie Windows jak w systemie Unix