sql >> Databáze >  >> RDS >> Oracle

Jaká je alternativa MySQL k funkci NEXT_DAY společnosti Oracle?

Hodím klobouk do ringu s ještě jiným přístupem:

Upravit: Poněkud opožděně si uvědomuji, že dotyčná funkce Oracle bere řetězec jako druhý argument, a tak to přesně neodpovídá požadavku. MySQL však již laskavě definovalo 0 - 6 jako pondělí - neděle a každopádně mám morální námitky proti použití řetězce jako argumentu pro tento typ věcí. Řetězec by pocházel buď z uživatelského vstupu nebo další mapování v kódu vyšší úrovně mezi číselnými a řetězcovými hodnotami. Proč nepředat celé číslo? :)

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

Rozdělit část, která určuje INTERVAL hodnota:

První část rovnice jednoduše získá posun mezi zadaným dnem v týdnu a dnem v týdnu zadaného data:

p_weekday - WEEKDAY(p_date)

Toto vrátí kladné číslo, pokud p_weekday je větší než WEEKDAY(p_date) a naopak. Pokud jsou stejné, bude vrácena nula.

ROUND() segment se používá k určení, zda požadovaný den v týdnu (p_weekday ) již došlo v aktuálním týdnu vzhledem k datu (p_date ) specifikováno. Takže například...

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

..vrací 0 , což označuje tu neděli (6 ) tento týden nenastal, jako 2019-01-25 je pátek. Stejně tak...

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

...vrací 1 protože středa (2 ) již prošel. Všimněte si, že to vrátí 0 pokud p_weekday je stejný jako den v týdnu p_date .

Tato hodnota (buď 1 nebo 0 ) se pak vynásobí konstantou 7 (počet dní v týdnu).

Pokud tedy p_weekday již došlo v aktuálním týdnu, přidá 7 k offsetu p_weekday - WEEKDAY(p_date) , protože tento posun by byl záporné číslo a my chceme datum v budoucnosti.

Pokud p_weekday ještě nenastane v aktuálním týdnu, pak můžeme jen přidat posun k aktuálnímu datu, protože posun bude kladné číslo. Proto sekce ROUND(...) * 7 se rovná nule a v podstatě se ignoruje.

Mým přáním tohoto přístupu bylo simulovat IF() podmínka matematicky. To by bylo stejně platné:

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

A v zájmu objektivity při spuštění 1M iterací několikrát každé funkce IF -založená verze byla v průměru o 4,2 % rychlejší než ROUND -založená verze.



  1. Import souboru .sql na windows do postgresql

  2. Jak exportovat data ve formátu CSV z SQL Server pomocí sqlcmd?

  3. PDO a caching, jak to implementovat do databázové třídy?

  4. Fond připojení Tomcat jdbc – opuštěná transakce vrácení zpět