Я использую базу данных оракула. я хочу выполнить один запрос для проверки данных между двумя датами.
NAME START_DATE
------------- -------------
Small Widget 15-JAN-10 04.25.32.000000 PM
Product 1 17-JAN-10 04.31.32.000000 PM
select * from <TABLENAME> where start_date
BETWEEN '15-JAN-10' AND '17-JAN-10'
Но я не получаю результатов выше запроса. Я думаю, что должен использовать "как" и "%". Но я не знаю, где использовать их. Пролейте некоторый свет на это.
заранее спасибо.
Судя по вашему выводу, похоже, вы определили START_DATE как метку времени. Если бы это была обычная дата, Oracle мог бы обрабатывать неявное преобразование. Но, поскольку это не так, вам нужно явно указать эти строки как даты.
SQL> alter session set nls_date_format = 'dd-mon-yyyy hh24:mi:ss'
2 /
Session altered.
SQL>
SQL> select * from t23
2 where start_date between '15-JAN-10' and '17-JAN-10'
3 /
no rows selected
SQL> select * from t23
2 where start_date between to_date('15-JAN-10') and to_date('17-JAN-10')
3 /
WIDGET START_DATE
------------------------------ ----------------------
Small Widget 15-JAN-10 04.25.32.000
SQL>
Но мы по-прежнему получаем только одну строку. Это потому, что в START_DATE есть элемент времени. Если мы не укажем компонент времени, Oracle по умолчанию установит полночь. Это нормально для из стороны МЕЖДУ
, но не для до стороны:
SQL> select * from t23
2 where start_date between to_date('15-JAN-10')
3 and to_date('17-JAN-10 23:59:59')
4 /
WIDGET START_DATE
------------------------------ ----------------------
Small Widget 15-JAN-10 04.25.32.000
Product 1 17-JAN-10 04.31.32.000
SQL>
редактировать
Если вы не можете передать компонент времени есть несколько вариантов. Один из них - изменить предложение WHERE, чтобы удалить элемент времени из критериев:
where trunc(start_date) between to_date('15-JAN-10')
and to_date('17-JAN-10')
Это может повлиять на производительность, потому что он дисквалифицирует любой индекс b-дерева на START_DATE. Вместо этого вам нужно будет создать индекс на основе функций.
В качестве альтернативы вы можете добавить элемент времени к дате в вашем коде:
where start_date between to_date('15-JAN-10')
and to_date('17-JAN-10') + (86399/86400)
Из-за этих проблем многие люди предпочитают избегать использования между
, проверяя границы даты следующим образом:
where start_date >= to_date('15-JAN-10')
and start_date < to_date('18-JAN-10')
Вам нужно преобразовать их в фактические даты вместо строк, попробуйте это:
SELECT *
FROM <TABLENAME>
WHERE start_date BETWEEN TO_DATE('2010-01-15','YYYY-MM-DD') AND TO_DATE('2010-01-17', 'YYYY-MM-DD');
Отредактировано для работы с форматом, как указано:
SELECT *
FROM <TABLENAME>
WHERE start_date BETWEEN TO_DATE('15-JAN-10','DD-MON-YY') AND TO_DATE('17-JAN-10','DD-MON-YY');
Как правильно отметила APC, ваш столбец start_date выглядит как TIMESTAMP, но также может быть TIMESTAMP WITH LOCAL TIMEZONE или TIMESTAMP WITH TIMEZONE. Это могло бы повлиять на любые запросы, которые вы выполняли по данным, если бы ваш сервер базы данных находился в другом часовом поясе, чем вы. Однако давайте будем простыми и предположим, что вы находитесь в том же часовом поясе, что и ваш сервер. Во-первых, чтобы придать уверенности, убедитесь, что start_date является типом данных TIMESTAMP.
Используйте команду SQLPlus DESCRIBE (или ее эквивалент в вашей среде IDE), чтобы убедиться, что этот столбец является типом данных TIMESTAMP.
например
DESCRIBE mytable
Должен сообщать:
Name Null? Type
----------- ----- ------------
NAME VARHAR2(20)
START_DATE TIMESTAMP
Если он указан как Type = TIMESTAMP, тогда вы можете запросить свои диапазоны дат с помощью простейшего преобразования даты TO_TIMESTAMP, которое не требует аргументов (или изображения).
Мы используем TO_TIMESTAMP, чтобы гарантировать, что любой индекс в столбце START_DATE учитывается оптимизатором. В ответе APC также отмечалось, что для этого столбца можно было создать индекс, основанный на функциях, и это повлияло бы на предикат SQL, но мы не можем комментировать это в этом запросе. Если вы хотите узнать, какие индексы были применены к таблице, задайте еще один вопрос, и мы ответим на него отдельно.
Итак, если имеется индекс для start_date, который является типом данных TIMESTAMP, и вы хотите, чтобы оптимизатор учел его, ваш SQL будет:
select * from mytable where start_date between to_timestamp('15-JAN-10') AND to_timestamp('17-JAN-10')+.9999999
+. 999999999 очень близок к 1, но не совсем 1, поэтому преобразование 17-JAN-10 будет как можно ближе к полуночи в этот день, поэтому запрос возвращает обе строки.
База данных будет видеть МЕЖДУ с 15-ЯНВ-10 00: 00: 00: 0000000 по 17-ЯНВ-10 23: 59: 59: 99999 и будет поэтому включите все даты с 15, 16 и 17 января 2010 года, независимо от компонента времени в метке времени.
Надеюсь, что это поможет.
Dazzer