|
Количество месяцев между датами
|
|||
---|---|---|---|
#18+
Подскажите, как доработать формулу расчета. У меня есть расчетный период, который определяется тремя параметрами: - тип периода: D (сутки), W (неделя), M (месяц), Y (год) - величина (натуральное число) - значение отсчета (отсутствует или натуральное число) Формулу расчетного периода можно записать например так: 3M - расчетным периодом является 3 календарных месяца, начиная с текущей даты 1M1 - расчетным периодом является один месяц, расчетный период всегда начинается с 1 числа месяца У меня есть две даты, известен расчетный период и мне нужно посчитать, сколько расчетных периодов размещается между этими двумя датами. Я это считаю таким выражением: Код: plsql 1. 2. 3. 4. 5. 6. 7.
Интервал задается датами ST.DATE_BEG и S.RECKONING_DATE, расчетный период задается TF.UNIT, TF.QTY и TF.ZERO. Но есть проблема с месячными периодами, когда длина месяцев разная. Например: select months_between(date'2022-02-28', date'2021-08-30') from dual - возвращает 5.94 А нужно получить 6. Не посоветуете, как это сделать? ... |
|||
:
Нравится:
Не нравится:
|
|||
01.10.2021, 17:11 |
|
Количество месяцев между датами
|
|||
---|---|---|---|
#18+
Может и посоветуем, если скажете, сколько должно получиться между датами: date'2022-02-28', date'2021-08-31' date'2022-02-28', date'2021-08-30' date'2022-02-28', date'2021-08-28' date'2022-02-27', date'2021-08-31' date'2022-02-27', date'2021-08-30' date'2022-02-20', date'2021-08-20' date'2022-02-15', date'2021-08-17' ... |
|||
:
Нравится:
Не нравится:
|
|||
01.10.2021, 17:15 |
|
Количество месяцев между датами
|
|||
---|---|---|---|
#18+
Alibek B., Смотря что Вам надо... Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22.
... |
|||
:
Нравится:
Не нравится:
|
|||
01.10.2021, 18:24 |
|
Количество месяцев между датами
|
|||
---|---|---|---|
#18+
С этими датами работает ИС на Perl и насколько я изучил исходники, алгоритм расчета следующий: Для дат с 1 по 28 считается число календарных месяцев. С 1 по 2 число месяцев будет больше единицы, со 2 по 1 число месяцев будет меньше единицы. Другими словами, идентично months_between. Если в конечном месяце количество дней меньше, чем число начальной даты, то результатом будет целое число (месяцев). Можно сказать, что в этом случае для обоих дат используется число конечного месяца. То есть с 31 января до 28 февраля ровно месяц, как и с 28 января до 28 февраля. Если в начальном месяце количество дней меньше, чем число конечной даты, то опять таки, считается как months_between. С 28 февраля до 29 марта будет больше единицы (если только год не високосный). Выражение у меня и так громоздкое, и если в него добавить case и least, то получится вообще нечто нечитаемое. Но может быть есть какой-то хитрый и изящный способ? ... |
|||
:
Нравится:
Не нравится:
|
|||
01.10.2021, 18:42 |
|
Количество месяцев между датами
|
|||
---|---|---|---|
#18+
Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42.
... |
|||
:
Нравится:
Не нравится:
|
|||
01.10.2021, 20:04 |
|
Количество месяцев между датами
|
|||
---|---|---|---|
#18+
Да, примерно так, только в моем случае вместо dt_from будет здоровенное выражение (ну либо нужно оборачивать в подзапрос). Спасибо за готовый пример, попробую его подставить в свой запрос. Я думал, что может быть получится выражение переписать так, чтобы оно было более компактным. Например вместо case when ... < ... просто вычитать из первой даты определенное значение. Но не смог придумать, как именно это сделать. ... |
|||
:
Нравится:
Не нравится:
|
|||
01.10.2021, 20:18 |
|
Количество месяцев между датами
|
|||
---|---|---|---|
#18+
Alibek B., Используйте MONTHS_BETWEEN, как показано выше. Или договоритесь с постановщиком задачи, что речь идет не про "месяцы", а про "тридцатидневки", например. ... |
|||
:
Нравится:
Не нравится:
|
|||
02.10.2021, 21:04 |
|
Количество месяцев между датами
|
|||
---|---|---|---|
#18+
Alibek B. Да, примерно так, интервал в месяцах, понятие размытое, хотя часто применяется, через 6 месяцев, не раньше чем за месяц, депозит на пол года, тощо напр c 01 по 28 февраля = ровно 1 месяц у невысокосном году, начало 29 января, когда набежит 1 месяц? "депозит на месяц", когда за процкнтами приходить? .... stax ... |
|||
:
Нравится:
Не нравится:
|
|||
04.10.2021, 09:09 |
|
Количество месяцев между датами
|
|||
---|---|---|---|
#18+
Понятие месяца можно обозначить так: берется последний день месяца для конечной даты, если в начальной дате тоже последний день месяца, либо номер дня больше количества дней в конечном месяце. Согласен, что несколько искусственно, но может быть такая трактовка месяца уже есть в какой-нибудь финансовой функции из дополнительных пакетов. Но раз нет, то нет. Наверное есть смысл самому написать такую функцию в виде package в теле PL/SQL кода (не добавляя в БД). Не подскажите, как следует делать эту функцию, чтобы она была эффективной при использовании в SQL? ... |
|||
:
Нравится:
Не нравится:
|
|||
04.10.2021, 09:15 |
|
Количество месяцев между датами
|
|||
---|---|---|---|
#18+
Alibek B. Наверное есть смысл самому написать такую функцию в виде package в теле PL/SQL кода (не добавляя в БД). что имеется в ввиду под "не добавляя в БД"? ..... stax ... |
|||
:
Нравится:
Не нравится:
|
|||
04.10.2021, 09:50 |
|
Количество месяцев между датами
|
|||
---|---|---|---|
#18+
Попробовал сделать так: Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36.
Но получаю ошибку ORA-06550 (функция не может быть использована в SQL). Это из-за декларативных операторов (IF)? Или функции в анонимном блоке использовать нельзя? ... |
|||
:
Нравится:
Не нравится:
|
|||
04.10.2021, 09:56 |
|
Количество месяцев между датами
|
|||
---|---|---|---|
#18+
Stax что имеется в ввиду под "не добавляя в БД"? Не создавая объекты в БД. ... |
|||
:
Нравится:
Не нравится:
|
|||
04.10.2021, 09:57 |
|
Количество месяцев между датами
|
|||
---|---|---|---|
#18+
Alibek B., так нельзя SQL не видит Вашу ф-цию у Вас 10-ка, и "Не создавая объекты в БД", печалька ..... stax ... |
|||
:
Нравится:
Не нравится:
|
|||
04.10.2021, 10:05 |
|
Количество месяцев между датами
|
|||
---|---|---|---|
#18+
Понятно, спасибо. Тогда буду делать package. Есть ли смысл избегать в этой функции (которая будет использоваться в SQL) декларативных подходов и обходиться сложным case? Или никакой выгоды для производительности/эффективности это не даст? ... |
|||
:
Нравится:
Не нравится:
|
|||
04.10.2021, 10:11 |
|
Количество месяцев между датами
|
|||
---|---|---|---|
#18+
Alibek B., "сложный case" сопровождать тяжело зы создайте две ф-ции и сравните сколько мкс Вы выиграете .... stax ... |
|||
:
Нравится:
Не нравится:
|
|||
04.10.2021, 10:16 |
|
Количество месяцев между датами
|
|||
---|---|---|---|
#18+
Подскажите, чем может быть вызван такой подход разработчика? В базе данных ИС есть несколько вспомогательных функций, которые написаны примерно так: Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16.
Хочу в этот же package добавить функцию period_count, которая будет подсчитывать нужное мне значение между двумя датами. В функцию передается идентификатор, по которому из таблицы считываются основные характеристики периода (тип, количество, отсчет). Почему сделано именно так? Я бы скорее характеристики периода передал бы в виде трех аргументов (чтобы в теле функции не делать отдельного запроса). Или есть какие-то причины, чтобы делать именно так? ... |
|||
:
Нравится:
Не нравится:
|
|||
04.10.2021, 12:17 |
|
Количество месяцев между датами
|
|||
---|---|---|---|
#18+
Alibek B., так решил архитектор если характеристики "идентификатора" поменяются, то код не приденся менять ..... stax ... |
|||
:
Нравится:
Не нравится:
|
|||
04.10.2021, 13:16 |
|
Количество месяцев между датами
|
|||
---|---|---|---|
#18+
Сделал так: Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59.
Схитрил так: months_between(d2+1, d1+1) Вероятно нужно будет добавить проверку (не хитрить, если обе даты меньше последнего дня месяца), но все равно получилось намного компактнее. Может быть я что-то упускаю? ... |
|||
:
Нравится:
Не нравится:
|
|||
04.10.2021, 14:25 |
|
Количество месяцев между датами
|
|||
---|---|---|---|
#18+
Alibek B., Использовать функции MONTHS_BETWEEN и ADD_MONTHS, согласовав это с ответственными представителями бизнеса. ... |
|||
:
Нравится:
Не нравится:
|
|||
04.10.2021, 16:45 |
|
Количество месяцев между датами
|
|||
---|---|---|---|
#18+
Так не выйдет. Месяцы считаются в биллинговой системе. Мне же нужно сделать отчет, который будет учитывать месяцы точно так, как их учитывает биллинговая система. Как именно это она делает — я выяснил, теперь нужно воспроизвести в SQL. ... |
|||
:
Нравится:
Не нравится:
|
|||
04.10.2021, 16:57 |
|
Количество месяцев между датами
|
|||
---|---|---|---|
#18+
Alibek B. Как именно это она делает — я выяснил, ... иногда потом оказывается, что (напр. в высокосном году), если ... ps использовать напрямую ф-цию из билинга не разрешают? ..... stax ... |
|||
:
Нравится:
Не нравится:
|
|||
04.10.2021, 17:25 |
|
|
start [/forum/topic.php?fid=52&msg=40101421&tid=1879853]: |
0ms |
get settings: |
9ms |
get forum list: |
13ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
172ms |
get topic data: |
9ms |
get forum data: |
2ms |
get page messages: |
50ms |
get tp. blocked users: |
2ms |
others: | 12ms |
total: | 277ms |
0 / 0 |