Программирование >>  Преобразование значений null 

1 ... 91 92 93 [ 94 ] 95 96 97 ... 219


01-JUN-2005

Далее, используя функцию MONTH, получаем месяц текущей даты и с помощью простого выражения CASE определяем, является ли первый день этого месяца понедельником или нет:

select dy, month(dy) mth,

case when dayname(dy)=Monday

then 1 else 0 end is monday from (

select (current date-day(current date) day +1 day) dy from t1

) tmp1

DY MTH IS MONDAY

01-JUN-2005 6 0

После этого используем рекурсивные возможности оператора WITH и последовательно добавляем по одному дню, начиная с первого дня месяца, до тех пор пока не дойдем до первого дня следующего месяца. В ходе этого с помощью выражения CASE отбираем понедельники (отмечая их флагом 1 ). Результат рекурсивного представления Х частично показан ниже:

with x (dy,mth,is monday) as (

select dy,month(dy) mth,

case when dayname(dy)=Monday

then 1 else 0 end is monday from (

select (current date-day(current date) day +1 day) dy from t1

) tmp1 union all

select (dy +1 day), mth,

case when dayname(dy +1 day)=Monday then 1 else 0

end from x

where month(dy +1 day) = mth

вычитания 10 из 10-го апреля будем иметь последний день марта). После этого вычитания просто добавляем один день, чтобы получить первый день текущего месяца:

select (current date-day(current date) day +1 day) dy from t1



select * from x

DY MTH IS MONDAY

01-JUN-2005 6 0

02-JUN-2005 6 0

03-JUN-2005 6 0

04-JUN-2005 6 0

05-JUN-2005 6 0

06-JUN-2005 6 1

07-JUN-2005 6 0

08-JUN-2005 6 0

Значения 1 столбца IS MONDAY будут соответствовать понедельникам. Таким образом, заключительный шаг - применяя агрегатные функции MIN и MAX к строкам, в которых значение поля IS MON-DAY равно 1, находим первый и последний понедельники месяца.

Oracle

Функция NEXT DAY значительно упрощает решение этой задачи. Чтобы найти первый понедельник текущего месяца, сначала посредством некоторых вычислений с привлечением функции TRUNC возвращаем последний день предыдущего месяца:

select trunc(sysdate,mm)-1 dy from dual

31-MAY-2005

Затем используем функцию NEXT DAY, чтобы найти первый понедельник после последнего дня предыдущего месяца (т. е. первый понедельник текущего месяца):

select next day(trunc(sysdate,mm)-1,MONDAY) first monday from dual

FIRST MONDAY

06-JUN-2005

Чтобы найти последний понедельник текущего месяца, сначала с помощью функции TRUNC возвращаем первый день текущего месяца:

select trunc(sysdate,mm) dy from dual

01-JUN-2005



23-JUN-2005

Здесь мы возвращаемся на семь дней от последнего дня месяца, чтобы гарантированно получить, по крайней мере, по одному разу каждый день недели. Последний шаг - использовать функцию NEXT DAY, чтобы найти следующий (и последний) понедельник месяца:

select next day(last day(trunc(sysdate,mm))-7,MONDAY) last monday from dual

LAST MONDAY

27-JUN-2005 PostgreSQL и MySQL

В PostgreSQL и MySQL используется аналогичный подход, отличие состоит лишь в вызываемых функциях. Cоответствующие запросы предельно просты, несмотря на их размеры; некоторые издержки возникают при поиске первого и последнего понедельников текущего месяца.

Первый шаг - найти первый день текущего месяца. Следующий шаг -определить первый понедельник месяца. Поскольку специальной функции, которая возвращала бы следующую дату, соответствующую заданному дню недели, нет, необходимо прибегнуть к небольшим вычислениям. Выражение CASE, начинающееся в строке 7 (любого решения), вычисляет разницу между числовым значением дня недели первого дня месяца и числовым значением, соответствующим понедельнику. Исходя из того, что функция TO CHAR (PostgresSQL) с форматной маской D или d и функция DAYOFWEEK (MySQL) для дней недели от воскресенья до субботы возвращают числовые значения от 1 до 7, понедельник всегда будет представлен цифрой 2. Сначала выражение CASE проверяет знак (SIGN) полученной разности между первым днем месяца (каким бы он ни был) и числовым значением понедельника (2). Если результат равен 0, первый день месяца выпадает на понедельник, и это первый понедельник месяца. Если результат равен -1, первый день месяца выпадает на воскресенье, и чтобы найти первый понедельник, надо просто добавить в первому дню месяца разницу в днях между 2 и 1 (числовые значения понедельника и воскресенья соответственно).

Если возникают сложности с пониманием логики этих операций, забудьте о названиях дней недели и оперируйте только числами. Например, пусть первым днем месяца является


Следующий шаг - находим последнюю неделю (последние семь дней) месяца. С помощью функции LAST DAY получаем последний день месяца и вычитаем семь дней:

select last day(trunc(sysdate,mm))-7 dy from dual



1 ... 91 92 93 [ 94 ] 95 96 97 ... 219

© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика