|
Программирование >> Преобразование значений null
01-OCT-1983 01-NOV-1983 01-DEC-1983 На данный момент мы имеем все необходимые месяцы. Выполняем внешнее объединение с EMP.HIREDATE. Поскольку в START DATE хранятся первые дни месяцев, значения EMP.HIREDATE необходимо преобразовать в первые дни соответствующих месяцев с помощью функции TRUNC. Наконец, применяем к EMP.HIREDATE агрегатную функцию COUNT. PostgreSQL В данном решении для получения всех необходимых месяцев используется функция GENERATE SERIES. Если GENERATE SERIES недоступна, можно обратиться к сводной таблице, как в решении для HIREDATE функции TRUNC и ADD MONTHS вместе с функциями MIN и MAX: select min(trunc(hiredate,y)) start date, add months(max(trunc(hiredate,y)),12) end date from emp START DATE END DATE 01-JAN-1980 01-JAN-1984 Затем, начиная со START DATE, многократно добавляем по одному месяцу, чтобы получить все месяцы, необходимые для формирования окончательного результирующего множества. Значение END DATE соответствует следующему дню после окончания рассматриваемого периода. Ничего страшного, мы прекратим рекурсивное добавление месяцев по достижении END DATE (не включая это значение в результат). Полученные месяцы частично показаны ниже: with x as ( select add months(start date,level-1) start date from ( select min(trunc(hiredate,y)) start date, add months(max(trunc(hiredate,y)),12) end date from emp ) connect by level <= months between(end date,start date) select * from x START DATE 01-JAN-1980 01-FEB-1980 01-MAR-1980 Для получения необходимого количества месяцев используем значение, возвращенное представлением V, как второй параметр GENERA-TE SERIES. Следующий шаг - найти начальную дату, с которой начинается рекурсивное добавление месяцев для формирования результирующего множества. Вложенный запрос Y находит начальную дату, применяя функцию DATE TRUNC к MIN(HIREDATE), и использует значения, возвращенные GENERATE SERIES, для добавления месяцев. Результаты частично показаны ниже: select cast(e.start date + (x.id * interval 1 month) as date) as mth from generate series (0,(select mths from v)) x(id), ( select cast( date trunc(year,min(hiredate)) MySQL. Первый шаг - понять представление V. Это представление находит, сколько месяцев требуется возвратить, определяя граничные даты диапазона. Для получения граничных дат во вложенном запросе Х представления V используются наибольшее и наименьшее значения HIREDATE (выявленные функциями MIN и MAX), как показано ниже: select cast(date trunc(year,min(hiredate)) as date) as first month, cast(cast(date trunc(year,max(hiredate)) as date) + interval 1 year as date) as last month from emp FIRST MONTH LAST MONTH 01-JAN-1980 01-JAN-1984 На самом деле значение LAST MONTH соответствует следующему дню после окончания рассматриваемого периода. Ничего страшного, поскольку при подсчете месяцев между этими двумя датами из значения LAST MONTH можно просто вычесть 1. Следующий шаг - с помощью функции AGE найти разницу между этими двумя датами в годах и умножить результат на 12 (и не забудьте вычесть 1!): select cast( extract(year from age(last month,first month))*12-1 as integer) as mths from ( select cast(date trunc(year,min(hiredate)) as date) as first month, cast(cast(date trunc(year,max(hiredate)) as date) + interval 1 year as date) as last month from emp ) x MTHS 01-OCT-1983 01-NOV-1983 01-DEC-1983 Теперь, имея все необходимые для формирования результирующего множества месяцы, проводим внешнее объединение с EMP.HIRE-DATE и используем агрегатную функцию COUNT, чтобы подсчитать, сколько сотрудников было принято на работу в каждом месяце. MySQL Сначала находим граничные даты, используя агрегатные функции MIN и MAX в сочетании с функциями DAYOFYEAR и ADDDATE. Вложенный запрос Х возвращает следующее результирующее множество: select adddate(min(hiredate),-dayofyear(min(hiredate))+1) min hd, adddate(max(hiredate),-dayofyear(max(hiredate))+1) max hd from emp MIN HD MAX HD 01-JAN-1980 01-JAN-1983 Далее, используя значение MAX HD, получаем последний месяц года: select min hd, date add(max hd,interval 11 month) max hd from ( select adddate(min(hiredate),-dayofyear(min(hiredate))+1) min hd, adddate(max(hiredate),-dayofyear(max(hiredate))+1) max hd from emp ) x MIN HD MAX HD 01-JAN-1980 01-DEC-1983 Теперь, имея граничные даты, добавляем месяцы, начиная с MIN HD до MAX HD включительно. Для получения необходимого количества строк используем сводную таблицу T500. Результаты частично показаны ниже: select date add(min hd,interval t500.id-1 month) mth from ( select min hd, date add(max hd,interval 11 month) max hd from ( as date) as start date from emp 01-JAN-1980 01-FEB-1980 01-MAR-1980
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |