|
Программирование >> Преобразование значений null
Чтобы найти первый и последний понедельники текущего месяца, используйте функции NEXT DAY и LAST DAY в сочетании с небольшим объемом операций над датами: select next day(trunc(sysdate,mm)-1,MONDAY) first monday, next day(last day(trunc(sysdate,mm))-7,MONDAY) last monday from dual PostgreSQL С помощью функции DATE TRUNC получите первый день месяца. После этого, используя простые вычисления над числовыми значениями дней недели (Вс.-Сб. соответствуют 1-7), находите первый и последний понедельники текущего месяца: дня недели и любого месяца. Поскольку один и тот же день недели повторяется каждые семь дней, получив первую соответствующую ему дату, можно добавить к ней 7 дней и найти вторую дату, а также добавить 14 дней и найти третью. Аналогично, если известна последняя соответствующая заданному дню недели дата месяца, вычитая 7 дней, получаем третью, а, вычитая 14, - вторую дату месяца. Используя рекурсивный оператор WITH, получаем все дни текущего месяца. С помощью выражения CASE отмечаем все понедельники. Первым и последним понедельниками будут самая ранняя и самая поздняя из отмеченных дат: 10 11 12 13 14 15 16 17 18 19 20 21 select from select from select from first monday, case to char(first monday+28,mm) when mth then first monday+28 else first monday+21 end as last monday case sign(cast(to char(dy,d) as integer)-2) when 0 then dy when -1 then dy+abs(cast(to char(dy,d) as integer)-2) when 1 then (7-(cast(to char(dy,d) as integer)-2))+dy end as first monday, mth cast(date trunc(month,current date) as date) as dy, to char(current date,mm) as mth ) x ) y MySQL Используйте функцию ADDDATE, чтобы получить первый день месяца. После этого путем простых вычислений над числовыми значениями дней недели (Вс.-Сб. соответствуют 1-7) находите первый и последний понедельники текущего месяца: 1 2 3 4 5 10 11 12 13 14 15 16 17 18 select from select from select from first monday, case month(adddate(first monday, 28)) when mth then adddate(first monday,28) else adddate(first monday,21) end last monday case sign(dayofweek(dy)-2) when 0 then dy when -1 then adddate(dy,abs(dayofweek(dy)-2)) when 1 then adddate(dy,(7-(dayofweek(dy)-2))) end first monday, adddate(adddate(current date,-day(current date)),1) dy, month(current date) mth ) x ) y SQL Server Используйте рекурсивный оператор WITH, чтобы получить все дни текущего месяца, и затем с помощью выражения CASE отметьте все понедельники. Первым и последним понедельниками будут самая ранняя и самая поздняя из отмеченных дат: 11 14 15 16 20 21 with as select from select from union select from where select from where x (dy,mth,is monday) dy,mth, case when datepart(dw,dy) = 2 then 1 else 0 dateadd(day,1,dateadd(day,-day(getdate()),getdate())) dy, month(getdate()) mth ) tmp1 all dateadd(day,1,dy), mth, case when datepart(dw,dateadd(day,1,dy)) = 2 then 1 else 0 month(dateadd(day,1,dy)) = mth min(dy) first monday, max(dy) last monday is monday = 1 Обсуждение DB2 и SQL Server В DB2 и SQL Server для решения поставленной задачи используются разные функции, но методики аналогичны. Если внимательно рассмотреть решения, то единственное отличие будет найдено в способе суммирования дат. В данном обсуждении анализируются оба решения. Для демонстрации промежуточных шагов используется код решения для DB2. Если в используемой версии SQL Server или DB2 рекурсивный оператор WITH не предоставляется, можно использовать технику, предлагаемую для PostgreSQL. Первый шаг при поиске первого и последнего понедельников текущего месяца состоит в получении первого дня месяца. Его поиском занимается вложенный запрос TMP1 в рекурсивном представлении Х. Сначала определяется текущая дата, а именно день месяца, соответствующий текущей дате. День месяца, соответствующий текущей дате, представляет, сколько дней месяца прошло (например, 10 апреля - это 10-й день апреля). Если вычесть это значение из текущей даты, получится последний день предыдущего месяца (например, в результате
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |