#sql #oracle
#sql #Oracle
Вопрос:
Я хочу найти вхождение определенного дня по отношению к месяцу, используя Oracle RDBMS.
Например: например, если сегодня 14 декабря 2020 года. Итак, это 2-й понедельник.
Поэтому я хочу, чтобы результат был равен 2. Аналогично.
Дополнительные примеры 7-Dec-2020 -> Вывод должен быть 1 (поскольку это первый понедельник декабря) 29-Dec-2020 -> Вывод должен быть 5 (поскольку это 5-й вторник декабря)
Комментарии:
1. Возможно, вам покажется интересной эта встроенная функция: docs.oracle.com/cd/E41183_01/DR/WeekDay.html
Ответ №1:
Вы можете использовать case
выражение:
select (case when extract(day from sysdate) <= 7 then '1st '
when extract(day from sysdate) <= 14 then '2nd '
when extract(day from sysdate) <= 21 then '3rd '
when extract(day from sysdate) <= 28 then '4th '
else '5th '
end) || to_char(sysdate, 'Day')
from dual;
Вот скрипка db<> .
Ответ №2:
- В предложении with я строю нужные даты (например, весь декабрь 2020 года) и использую аналитическую функцию row_number для ранжирования моих дат на основе формата ГГГГМД. Я использую D, а не DD, потому что D означает день недели. Я также использую nsl_parameter (nls_date_language), потому что начальный день не одинаков для всех стран
- Затем я преобразую столбец ранга (rnb) в дату, используя to_date(lpad(rnb, 2, ‘0’), ‘DD’). Я сделал это, так как мне нужно, чтобы oracle записал вхождение, используя этот формат даты ‘DDth’.
- Затем я объединяю результат с форматом «fmDay Месяц год»
with dates as (
select DATE '2020-12-01' level - 1 dt
, row_number()over (
partition by to_char(DATE '2020-12-01' level - 1, 'YYYYMMD','nls_date_language = ENGLISH')
order by DATE '2020-12-01' level - 1) rnb
from dual
connect by level <= 31
)
select dt
, Initcap(to_char(to_date(lpad(rnb, 2, '0'), 'DD'), 'DDth','nls_date_language = ENGLISH'))
||' '||to_char(dt, 'fmDay Month YYYY', 'nls_date_language = ENGLISH') Occurence
from dates
order by dt
;
Ответ №3:
Это всего лишь небольшая математика. Первые семь дней — это первое вхождение для каждого дня, следующие семь дней — второе вхождение и так далее. Итак, получите номер дня, например, 14, вычтите единицу и примените целочисленное деление, а затем снова добавьте единицу.
select trunc((extract(day from sysdate) - 1) / 7) 1 from dual;