#sql #oracle #datetime #business-objects #date-arithmetic
#sql #Oracle #дата и время #бизнес-объекты #дата-арифметика
Вопрос:
Я создал отчет в BusinessObjects WEBI, но я хотел бы настроить базовый SQL так, чтобы год в диапазоне дат менялся в зависимости от времени выполнения запроса, оставляя день и месяц неизменными
Этот пример …
WHERE
ACT_ENDDT BETWEEN '01-10-2019 00:00:00' AND '30-09-2020 00:00:00'
… желательно, если бы я запустил запрос сейчас (текущий год -1 И текущий год соответственно), но если бы я должен был выполнить этот запрос в 2021 году, я хочу, чтобы эти годы изменились на 2020 и 2021 соответственно, сохраняя день и месяцы одинаковыми (10/1 и 9/30).
Я просмотрел несколько ресурсов, таких как sqltutorial и w3schools, но я едва ли новичок в этом и не могу понять, как заставить это работать. Я также попробовал решение, представленное здесь в потоке 28707795, как таковое:
ACT_ENDDT BETWEEN DATEFROMPARTS(YEAR(getdate())-1,10,1) AND DATEFROMPARTS(YEAR(getdate()),9,30)
… но в итоге появляется сообщение о том, что DATEFROMPARTS является недопустимым идентификатором.
Есть ли способ жестко запрограммировать часть даты и прикрепить к ней модификатор только для года, например ... BETWEEN '01-10-'amp;[*currentyear* - 1] ...
?
Спасибо.
Комментарии:
1. Пожалуйста, укажите в своем вопросе базу данных, которую вы используете: mysql, oracle, sqlserver …?
2. Примечание:
ACT_ENDDT BETWEEN '01-10-2019 00:00:00' AND '30-09-2020 00:00:00'
пропускает все моменты времени после 30-09-2020 00:00:00, даже если дневная часть по-прежнему равна 30-09-2020. Есть вероятность, что это не является преднамеренным иACT_ENDDT >= '01-10-2019 00:00:00' AND ACT_ENDDT < '01-10-2020 00:00:00'
является более подходящим выражением.3. Что такое тип
ACT_ENDDT
данных? Если это строка,between
она не будет работать. Если это `дата, это не то, как вы пишете литералы даты .4. Хранятся ли ваши данные в базе данных Oracle? В Oracle нет таких функций, как DATEFROMPARTS и GETDATE. Если это действительно Oracle, и вы переходите из другого продукта базы данных, вам нужно будет изучить диалект Oracle. Отдельно от этого обратите пристальное внимание на обсуждение полузакрытых, полуоткрытых интервалов в ответе GMB; это очень распространенная ловушка для новичков. Убедитесь, что вы не пропустили даты (всегда даты-времена в Oracle!) с последнего дня вашего интервала. МЕЖДУ очень редко хорошо работает с интервалами дат.
Ответ №1:
Вы можете использовать артиметику даты следующим образом:
where act_enddt between trunc(sysdate, 'year') - interval '3' month
and trunc(sysdate, 'year') interval '9' month - interval '1' day
Интересно, может ли быть полезен полуоткрытый интервал:
where act_enddt >= trunc(sysdate, 'year') - interval '3' month
and act_enddt < trunc(sysdate, 'year') interval '9' month
Разница между двумя выражениями заключается в том, что последнее допускает даты между 30 октября в 00:00 и концом этого дня. Если ваши даты не имеют временного компонента, это не имеет значения (а второе выражение немного аккуратнее).
Ответ №2:
Вы можете использовать extract()
для извлечения части года sysdate
, выполнить с ней арифметические действия, например, вычесть единицу, объединить часть месяца и дня, чтобы завершить ее представлением даты, и преобразовать эту строку в date
with to_date()
.
Это
to_date(extract(YEAR FROM sysdate) - 1 || '-10-01', 'YYYY-MM-DD')
для вашего нижнего и
to_date(extract(YEAR FROM sysdate) || '-09-30', 'YYYY-MM-DD')
для вашей верхней границы.