Oracle
 sql >> база данни >  >> RDS >> Oracle

Каква е алтернативата на MySQL на функцията NEXT_DAY на Oracle?

Ще хвърля шапката си на ринга с още един подход:

Редактиране: С малко закъснение разбирам, че въпросната функция на Oracle приема низ като втори аргумент и така това не отговаря точно на изискването. Въпреки това MySQL вече любезно е дефинирал 0 - 6 като понеделник - неделя и така или иначе имам морални възражения срещу използването на низ като аргумент за този тип неща. Низът идва или от потребителско въвеждане или още едно картографиране в код от по-високо ниво между числови и низови стойности. Защо не подадете цяло число? :)

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

За да разделите частта, която определя INTERVAL стойност:

Първата част от уравнението просто получава отместването между посочения ден от седмицата и деня от седмицата на посочената дата:

p_weekday - WEEKDAY(p_date)

Това ще върне положително число, ако p_weekday е по-голямо от WEEKDAY(p_date) и обратно. Ще бъде върната нула, ако са еднакви.

ROUND() сегмент се използва за определяне дали исканият ден от седмицата (p_weekday ) вече се е случило през текущата седмица спрямо датата (p_date ) посочено. И така, като пример...

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

..връща 0 , указващ тази неделя (6 ) не се е случило тази седмица, тъй като 2019-01-25 е петък. По същия начин...

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

...връща 1 защото сряда (2 ) вече е минало. Имайте предвид, че това ще върне 0 ако p_weekday е същият като деня от седмицата на p_date .

Тази стойност (или 1 или 0 ) след това се умножава по константата 7 (броя дни в седмицата).

Следователно, ако p_weekday вече се е случило през текущата седмица, то ще добави 7 към отместването p_weekday - WEEKDAY(p_date) , тъй като това отместване би било отрицателно число и ние искаме дата в бъдещето.

Ако p_weekday все още не се е случило през текущата седмица, тогава можем просто да добавим отместването към текущата дата, защото отместването ще бъде положително число. Оттук и секцията ROUND(...) * 7 е равно на нула и по същество се игнорира.

Желанието ми за този подход беше да симулирам IF() състояние математически. Това би било еднакво валидно:

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

И в интерес на обективността, при изпълнение на 1 милион итерации няколко пъти на всяка функция IF -базираната версия беше средно с около 4,2% по-бърза от ROUND -базирана версия.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Проблем с преобразуване на Oracle SQL DATE при използване на iBATIS чрез Java JDBC

  2. java.lang.UnsupportedOperationException:org.hibernate.dialect.Oracle10gDialect не поддържа набори от резултати чрез съхранени процедури

  3. Как да създадете дъмп с Oracle PL/SQL Developer?

  4. Как да получите информация от потребителя по време на изпълнение

  5. Как да получите достъп до системните таблици на Oracle от вътрешността на PL/SQL функция или процедура?