|
Программирование >> Преобразование значений null
date format( adddate(current date, -dayofmonth(current date)+1), %m) mth from t1 ) x, t500 where t500.id <= 31 and date format(adddate(x.dy,t500.id-1),%m) = x.mth WK DM DW 22 01 4 22 02 5 25 21 25 22 2b 30 5 Теперь для каждого дня текущего месяца мы имеем: двузначный номер дня месяца (DM), однозначный номер дня недели (DW) и двузначный ISO-номер недели (WK). Эту информацию можно использовать в выражении CASE для установления соответствия между каждым значением DM (каждым днем месяца) и днем недели. Результаты частично показаны ниже: select case dw when 2 then dm end as Mo, case dw when 3 then dm end as Tu, case dw when 4 then dm end as We, case dw when 5 then dm end as Th, case dw when 6 then dm end as Fr, case dw when 7 then dm end as Sa, case dw when 1 then dm end as Su from ( select date format(dy,%u) wk, date format(dy,%d) dm, date format(dy,%w)+1 dw from ( select adddate(x.dy,t500.id-1) dy, x.mth from ( select adddate(current date,-dayofmonth(current date)+1) dy, date format( adddate(current date, -dayofmonth(current date)+1), %m) mth from t1 ) x, t500 where t500.id <= 31 and date format(adddate(x.dy,t500.id-1),%m) = x.mth ) y WK MO TU WE TH FR SA SU 22 01 22 02 22 03 22 04 22 05 23 06 23 07 23 08 23 09 23 10 23 11 23 12 Как видно из частичного вывода, каждый день недели возвращен в отдельной строке. В каждой строке номер дня располагается в столбце, соответствующем дню недели, на который данный день выпадает. Теперь наша задача - свести все дни одной недели в одну строку. Для этого используем агрегатную функцию MAX и группировку строк по столбцу WK (ISO-номеру недели). Чтобы обеспечить правильное расположение дней, упорядочиваем результаты по WK. Окончательный вывод показан ниже: select max(case dw when 2 then dm end) as Mo, max(case dw when 3 then dm end) as Tu, max(case dw when 4 then dm end) as We, max(case dw when 5 then dm end) as Th, max(case dw when 6 then dm end) as Fr, max(case dw when 7 then dm end) as Sa, max(case dw when 1 then dm end) as Su from ( select date format(dy,%u) wk, date format(dy,%d) dm, date format(dy,%w)+1 dw from ( select adddate(x.dy,t500.id-1) dy, x.mth from ( select adddate(current date,-dayofmonth(current date)+1) dy, date format( adddate(current date, -dayofmonth(current date)+1), %m) mth from t1 ) x, t500 where t500.id <= 31 and date format(adddate(x.dy,t500.id-1),%m) = x.mth ) y group by wk order by wk MO TU WE TH FR SA SU 01 02 03 04 05 0b 07 08 09 10 11 12 13 14 15 1b 17 18 19 20 21 22 23 24 25 2b 27 28 29 30 SQL Server Начинаем с возвращения каждого дня месяца в отдельной строке. Сделать это можно с помощью рекурсивного оператора WITH или, если используемая версия SQL Server не поддерживает рекурсивный WITH, применяя сводную таблицу, как в решении для MySQL. В каждой возвращаемой строке содержатся следующие элементы: порядковый номер дня месяца (под псевдонимом DM), день недели (под псевдонимом DW), текущий месяц (под псевдонимом MTH) и ISO-номер недели (под псевдонимом WK). Рекурсивное представление Х до выполнения рекурсии (верхняя часть оператора UNION ALL) показано ниже: select dy, day(dy) dm, datepart(m,dy) mth, datepart(dw,dy) dw, case when datepart(dw,dy) = 1 then datepart(ww,dy)-1 else datepart(ww,dy) end wk from ( select dateadd(day,-day(getdate())+1,getdate()) dy from t1 ) x DY DM MTH DW WK 01-JUN-2005 1 b 4 23 Следующий этап - пошагово увеличиваем значение DM до тех пор, пока не будут получены все дни месяца. Для каждого дня возвращаем также соответствующие ему день недели и ISO-номер недели. Результаты частично показаны ниже: with x(dy,dm,mth,dw,wk) as ( select dy, day(dy) dm, datepart(m,dy) mth,
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |