SELECT Stuff
FROM Table
WHERE datefield BETWEEN (currentdate - 28) AND (current_date - 1)
Возвращает значения за 28 дней до текущей даты в то же время суток, что и сейчас, и за 1 день до текущей даты в то же время суток, что и сейчас.Таким образом, если вы введете этот параметр в 10:23
сегодня, то он получит результаты до 10:23
вчера, а если все ваши вчерашние результаты были введены во второй половине дня, то они не будут включены в результаты.
SELECT Stuff
FROM Table
WHERE TO_DATE(datefield, 'YYYY-MM-DD') = TO_DATE((current_date - 1), 'YYYY-MM-DD')
TO_DATE( date_string, format_model )
принимает строку в качестве первого аргумента, поэтому Oracle неявно преобразует вашу дату в строку, используя параметр сеанса NLS_DATE_FORMAT
.Таким образом, ваш запрос эффективен:
SELECT Stuff
FROM Table
WHERE TO_DATE(
TO_CHAR(
datefield,
( SELECT VALUE FROM NLS_SESSION_PARAMETERS WHERE PARAMETER = 'NLS_DATE_FORMAT' )
),
'YYYY-MM-DD'
)
=
TO_DATE(
TO_CHAR(
(current_date - 1),
( SELECT VALUE FROM NLS_SESSION_PARAMETERS WHERE PARAMETER = 'NLS_DATE_FORMAT' )
),
'YYYY-MM-DD'
)
Во-первых, никогда не полагайтесь на неявное преобразование.Во-вторых, в зависимости от того, что ваш параметр сеанса NLS_DATE_FORMAT
, ваш запрос также: вызовет исключение, если модель формата не соответствует YYYY-MM-DD
;или дайте вам бессмысленные даты (т. е. если ваша стандартная модель формата RR-MM-DD
, то вы потеряете века от ваших дат; если это DD-MM-YY
, то вы поменяете дни и годы - что может «работать» [т.е.поднять исключение] на следующее десятилетие или около того, а затем ужасно взорваться в феврале 2029 года);или это будет работать.Тем не менее, это параметр сеанса, поэтому пользователи могут его изменить, и ваш запрос случайным образом перестанет работать без изменения вашего SQL.
Если предположить, что ваш NLS_DATE_FORMAT
равен YYYY-MM-DD
, тогда это будет эффективно урезать ваши даты, и вы можетесделать это намного проще, используя:
SELECT Stuff
FROM Table
WHERE TRUNC(datefield) = TRUNC(current_date - 1)
Это позволит получить все результаты (независимо от времени суток) за вчерашний день.
То, что вы, вероятно, хотите:
SELECT Stuff
FROM Table
WHERE datefield >= TRUNC( currentdate - 28 )
AND datefield < TRUNC( current_date )
Поскольку все результаты будут получены с полуночи 28 дней назад до полуночи сегодня.
Если это не сработает, вам необходимо проверить значения даты:
SELECT TO_CHAR( datevalue, 'YYYY-MM-DD HH24:MI:SS' )
FROM table;
Возможно, вы обнаружите, что даты хранятся вместе с годом в 1-м веке нашей эры (т. Е. 0018-10-24 09:50:00
в качестве значения), и это (вероятно) будет связано с тем, что даты были загружены в виде строки с двухзначным годом (YY-MM-DD
) когда ожидается 4-значный год (YYYY-MM-DD
), поэтому Oracle будет считать, что столетие равно 0.