Oracle дата" между " запрос
Я использую базу данных Oracle. я хочу выполнить один запрос, чтобы проверить данные между двумя датами.
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'
но я не получаю никаких результатов из запроса выше. Я думаю, что я должен использовать " нравится "и"%". Но я не знаю, где их использовать. Пожалуйста, пролей свет на это.
спасибо заранее.
5 ответов
судя по вашему выводу, похоже, что вы определили 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 по умолчанию установит полночь. Это прекрасно для С стороне BETWEEN
но не для до сторона:
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, чтобы удалить элемент time из критериев:
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)
из-за этих проблем многие люди предпочитают избегать использования between
проверяя границы дат, как это:
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 кажется меткой времени, но это может быть метка времени с локальным часовым поясом или меткой времени с типом данных часового пояса. Это может повлиять на любые запросы, которые вы делаете с данными, если ваш сервер баз данных находится в другом часовом поясе. Однако давайте оставим это простым и предположим, что вы находитесь в том же часовом поясе, что и ваш сервер. Во-первых, чтобы дать вам уверенность, проверьте, что start_date является типом данных TIMESTAMP.
используйте команду sqlplus DESCRIBE (или эквивалент в IDE), чтобы проверить, что этот столбец является типом данных TIMESTAMP.
например
опишите 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, поэтому преобразование 17-JAN-10 будет как можно ближе к полуночи в этот день, поэтому вы запрашиваете возврат обеих строк.
база данных будет видеть между, как из 15-янв-10 00:00:00:0000000 to 17-янв-10 23:59:59:99999 и поэтому будет включать в себя все даты с 15,16 и 17 января 2010 года независимо от компонента времени метки времени.
Надежда эта помощь.
Dazzer
Дата Между Запросом
SELECT *
FROM emp
WHERE HIREDATE between to_date (to_char(sysdate, 'yyyy') ||'/09/01', 'yyyy/mm/dd')
AND to_date (to_char(sysdate, 'yyyy') + 1|| '/08/31', 'yyyy/mm/dd');
следующий запрос также может быть использован:
select *
from t23
where trunc(start_date) between trunc(to_date('01/15/2010','mm/dd/yyyy')) and trunc(to_date('01/17/2010','mm/dd/yyyy'))