|
Программирование >> Преобразование значений null
to char(sysdate,mm) mth from dual connect by level <= 31 where curr mth = mth select * from x DY WK DM DW CU MT 01-JUN-2005 22 01 4 0b 0b 02-JUN-2005 22 02 5 0b 0b 21-JUN-2005 25 21 3 0b 0b 22-JUN-2005 25 22 4 0b 0b 30-JUN-2005 2b 30 5 0b 0b Здесь мы получаем все дни текущего месяца, каждый из которых выведен в отдельной строке. В каждой строке представлены следующие данные: двузначный номер дня месяца, двузначный номер месяца, однозначный номер дня недели (1-7 для Вс.-Сб.) и двузначный ISO-номер недели. Имея в своем распоряжении всю эту информацию, с помощью выражения CASE можно определить, на какой день недели выпадает каждое из значений столбца DM (каждый день месяца). Результаты частично показаны ниже: 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, to char(sysdate,mm) mth from dual connect by level <= 31 ) where curr mth = mth select wk,
22 01 22 03 22 04 22 05 23 06 23 07 23 08 23 09 23 10 23 11 23 12 Как видно из частично представленного результата, каждый день каждой недели возвращается в отдельной строке, но номер дня располагается в одном из семи столбцов в соответствии с днем недели. Теперь остается только собрать все дни одной недели в одну строку. Чтобы возвратить все дни недели в одной строке, используем агрегатную функцию MAX и группировку по значениям столбца WK (ISO-номеру недели). Чтобы обеспечить верное расположение дней, упорядочиваем результаты по WK. Окончательный результат приведен ниже: with x as ( select * from ( select 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, to char(sysdate,mm) mth from dual connect by level <= 31 ) where
from x group by wk order by wk MO TU WE TH FR SA SU from x 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 PostgreSQL С помощью функции GENERATE SERIES возвращаем каждый день месяца в отдельной строке. Если используемая версия PostgreSQL не поддерживает GENERATE SERIES, можно применить сводную таблицу, как показано в решении для MySQL. Для каждого дня месяца возвращаем следующую информацию: порядковый номер дня месяца (под псевдонимом DM), день недели (под псевдонимом DW), текущий месяц, с которым мы работаем (под псевдонимом MTH), и ISO-номер недели (под псевдонимом WK). Форматирование и явное приведение делают это решение тяжелым для восприятия, но на самом деле оно довольно простое. Результаты, возвращаемые вложенным запросом Х, частично показаны ниже: select cast(date trunc(month,current date) as date)+x.id as dy, to char( cast( date trunc(month,current date) as date)+x.id,iw) as wk, to char( cast( date trunc(month,current date) as date)+x.id,dd) as dm, cast( to char( cast( date trunc(month,current date) as date)+x.id,d) as integer) as dw, to char( cast( date trunc(month,current date) as date)+x.id,mm) as curr mth, to char(current date,mm) as mth from generate series (0,31) x(id) DY WK DM DW CU MT 01-JUN-2005 22 01 4 0b 0b 02-JUN-2005 22 02 5 0b 0b 21-JUN-2005 25 21 3 0b 0b 22-JUN-2005 25 22 4 0b 0b 30-JUN-2005 2b 30 5 0b 0b
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |