|
Программирование >> Преобразование значений null
select (current date -day(current date) day +1 day) dy, day((current date -day(current date) day +1 day)) dm, month(current date) mth, dayofweek(current date -day(current date) day +1 day) dw, week iso(current date -day(current date) day +1 day) wk from t1 union all select dy+1 day, day(dy+1 day), mth, dayofweek(dy+1 day), week iso(dy+1 day) from x where month(dy+1 day) = mth select * from x
На данном этапе мы получаем все дни текущего месяца, а также следующие данные для каждого дня: двузначный номер дня месяца, двузначный номер месяца, однозначный номер дня недели (1-7 для Вс.-Сб.) и двузначный ISO-номер недели. Имея в своем распоряжении всю эту информацию, с помощью выражения CASE можно определить, на какой день недели выпадает каждое из значений столбца DM (каждый день месяца). Результаты частично показаны ниже: with x(dy,dm,mth,dw,wk) as ( select (current date -day(current date) day +1 day) dy, day((current date -day(current date) day +1 day)) dm, month(current date) mth, dayofweek(current date -day(current date) day +1 day) dw, week iso(current date -day(current date) day +1 day) wk from t1 union all select dy+1 day, day(dy+1 day), mth, dayofweek(dy+1 day), week iso(dy+1 day) from x where month(dy+1 day) = mth select wk, 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 x WK MO TU WE TH FR SA SU 22 01 22 02 22 03 22 04 22 05 23 0b 23 07 23 08 23 09 23 10 23 11 23 12 Как видно из частично представленных результатов, каждый день недели возвращается в отдельной строке. Теперь осталось только сгруппировать дни по неделям и собрать все дни одной недели в одну строку. Чтобы возвратить все дни недели в одной строке, используйте агрегатную функцию MAX и группировку по значениям столбца WK (ISO-но-меру недели). Чтобы правильно отформатировать календарь и обеспечить верное расположение дней, упорядочиваем результаты по WK. Окончательный результат приведен ниже: with x(dy,dm,mth,dw,wk) as ( select (current date -day(current date) day +1 day) dy, day((current date -day(current date) day +1 day)) dm, month(current date) mth, dayofweek(current date -day(current date) day +1 day) dw, week iso(current date -day(current date) day +1 day) wk from t1 union all select dy+1 day, day(dy+1 day), mth, dayofweek(dy+1 day), week iso(dy+1 day) from x where month(dy+1 day) = mth 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 x group by wk order by wk MO TU WE TH FR SA SU 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 Oracle В Oracle 9i Database начинаем с использования рекурсивного оператора CONNECT BY, с помощью которого получаем столько строк, сколько дней в заданном месяце. В более ранних версиях СУБД CONNECT BY не может таким образом использоваться. Вместо этого можно применить сводную таблицу, например T500, как в решении для MySQL. Для каждого дня месяца понадобится дополнительно получить следующие данные: порядковый номер дня месяца (под псевдонимом DM), день недели (под псевдонимом DW), текущий месяц (под псевдонимом MTH) и ISO-номер недели для каждого дня месяца (под псевдонимом WK). Результаты, возвращаемые представлением Х оператора WITH для первого дня текущего месяца, показаны ниже: select trunc(sysdate,mm) dy, to char(trunc(sysdate,mm),dd) dm, to char(sysdate,mm) mth, to number(to char(trunc(sysdate,mm),d)) dw, to char(trunc(sysdate,mm),iw) wk from dual DY DM MT DW WK 01-JUN-2005 01 06 4 22 Далее пошагово увеличиваем значение DM (перебираем дни месяца) до тех пор, пока не будут получены все дни текущего месяца. Для каждого дня месяца также возвращаем соответствующий ему день недели и ISO-номер недели, в которую попадает данный день. Результаты частично показаны ниже (полная дата для каждого дня приведена для ясности): with x as ( select * from ( select trunc(sysdate,mm)+level-1 dy, to char(trunc(sysdate,mm)+level-1,iw) wk, to char(trunc(sysdate,mm)+level-1,dd) dm, to number(to char(trunc(sysdate,mm)+level-1,d)) dw, to char(trunc(sysdate,mm)+level-1,mm) curr mth,
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |