Дата 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'

Но я не получаю результатов выше запроса. Я думаю, что должен использовать "как" и "%". Но я не знаю, где использовать их. Пролейте некоторый свет на это.

заранее спасибо.

51
задан Sandro Ferreira 23 April 2015 в 10:47
поделиться

3 ответа

Судя по вашему выводу, похоже, вы определили 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')
83
ответ дан 7 November 2019 в 10:01
поделиться

Вам нужно преобразовать их в фактические даты вместо строк, попробуйте это:

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');
22
ответ дан 7 November 2019 в 10:01
поделиться

Как правильно отметила 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

3
ответ дан 7 November 2019 в 10:01
поделиться
Другие вопросы по тегам:

Похожие вопросы: