Количество дней в месяце

У меня есть месячная сумма, которую мне нужно равномерно распределить по количеству дней в месяце. Данные выглядят так:

Month       Value
----------- ---------------
01-Jan-2012 100000
01-Feb-2012 121002
01-Mar-2012 123123
01-Apr-2012 118239

Я должен распределить сумму за январь на 31 день, сумму за февраль на 29 дней и сумму за март на 31 день.

Как я могу использовать PL/SQL, чтобы узнать, сколько дней в месяце, указанном в столбце месяца?


person Raj More    schedule 07.12.2012    source источник


Ответы (5)


Не используйте to_char() и прочее при выполнении арифметических операций с датами. Строки — это строки, а даты — это даты. Пожалуйста, уважайте типы данных и используйте это вместо этого:

1+trunc(last_day(date_column))-trunc(date_column,'MM')

Действительно, это правильно. Он вычисляет разницу между значением последнего дня месяца и значением первого (которое, очевидно, всегда равно 1, и поэтому нам нужно снова добавить эту 1) .

Вы не должны забывать использовать функцию trunc(), если ваши столбцы даты содержат время, потому что last_day() сохраняет компонент времени.

person UniversE    schedule 27.10.2016

Вы можете добавить месяц и вычесть две даты

SQL> ed
Wrote file afiedt.buf

  1  with x as (
  2      select date '2012-01-01' dt from dual union all
  3      select date '2012-02-01' from dual union all
  4      select date '2012-03-01' from dual union all
  5      select date '2012-01-31' from dual
  6    )
  7    select dt, add_months(trunc(dt,'MM'),1) - trunc(dt,'MM')
  8*     from x
SQL> /

DT        ADD_MONTHS(TRUNC(DT,'MM'),1)-TRUNC(DT,'MM')
--------- -------------------------------------------
01-JAN-12                                          31
01-FEB-12                                          29
01-MAR-12                                          31
31-JAN-12                                          31
person Justin Cave    schedule 07.12.2012
comment
попробуйте то же самое, используя 2012-01-31. Вы получаете 29 вместо 31, что неверно. - person Raj More; 17.12.2012
comment
@RajMore - я не уверен, что понимаю твою точку зрения. Если вы добавите 1 месяц к 2012-01-31, это даст вам 2012-02-29. Вычитание двух дает 29, что правильно. Конечно, это дает вам количество дней в феврале, а не в январе. Все образцы данных, которые вы опубликовали, относятся к первому числу месяца, а не к последнему дню месяца. Вы можете trunc(some_date, 'MM') преобразовать дату в первое число месяца, чтобы она соответствовала образцам данных, которые вы опубликовали. - person Justin Cave; 17.12.2012
comment
Я просто собрал образцы данных для примера — данные на самом деле разбросаны по всему месяцу. - person Raj More; 18.12.2012
comment
@RajMore. Когда вы собираете образцы данных, постарайтесь как можно больше охватить фактические варианты использования, которые вам нужно обработать. Если все ваши образцы данных указаны первыми, и вы не укажете, что реальные данные происходят в течение месяца, люди, естественно, решат, что вы просто сохраняете месяц в своих данных. Я обновил свой ответ, включив в него trunc. - person Justin Cave; 19.12.2012

Используйте следующий запрос Oracle:

select to_number(to_char(last_day(sysdate),'dd')) TotalDays from dual

Date_Parameter='01-Oct-2017'
select to_number(to_char(last_day('Date_Parameter'),'dd')) TotalDays from dual
person SAH    schedule 11.10.2017

person    schedule
comment
Вау, это то, что я называю pythonic :) - person Sauer; 12.06.2018

person    schedule
comment
Это не правильно. Рассмотрим 2016-10-31 в качестве входных данных. Возвращает 30 дней. - person UniversE; 27.10.2016
comment
Вопрос ясно показывает, что дата всегда будет первым числом месяца, так что это правильный ответ. Если у вас есть другое требование, вы можете выбрать add_months(TRUNC(my_date,'MM'), 1)-TRUNC(my_date,'MM') from dual; - person RET; 13.02.2020