Как искать дату в запросе, если используется sysdate

У меня есть запрос на соединение, который просматривает 2 таблицы и вводит даты между временными рамками. Я использовал sysdate при вставке данных. Когда я выбираю данные из таблицы, я вижу даты, однако я не знаю, как фильтровать данные по дате.

Я попытался в конце моего запроса, но я не получаю выбранных строк:

where dateofstart = '04-MAY-20';

Я также пробовал:

 where dateofstart = 'date '2020-05-010';

И, наконец, я попробовал:

 dateofstart between '10-May-20' and '16-May-20';

Я использую SQL Plus.


person Annon    schedule 06.05.2020    source источник
comment
Вам это помогает? stackoverflow.com/questions/23398632/   -  person kmoser    schedule 06.05.2020
comment
У вас есть несколько хороших ответов, но позвольте мне высказать одно побочное наблюдение. В приведенных выше примерах вы иногда используете 2-значные годы, а иногда 4-значные годы. Потратив 2 года на то, чтобы помочь исправить Y2K ..... пожалуйста, пожалуйста, пожалуйста, всегда используйте 4-значные годы. Без исключений!   -  person EdStevens    schedule 06.05.2020
comment
Это хорошая информация, большое спасибо   -  person Annon    schedule 07.05.2020


Ответы (3)


Если вы использовали SYSDATE как есть, это функция, которая содержит дату и время, например

SQL> alter session set nls_date_format = 'dd.mm.yyyy hh24:mi:ss';

Session altered.

SQL> select sysdate from dual;

SYSDATE
-------------------
06.05.2020 07:20:38

SQL>

и хранится как таковой в вашей таблице (я предполагаю, что тип данных столбца - DATE).

Следовательно, если вы искали where dateofstart = '04-MAY-20', вы сделали две ошибки:

  • you are comparing DATE datatype column with a string. Yes, '04-MAY-20' is a string; it looks like date to you and me, but to Oracle it is just a string. Oracle tries to implicitly convert it to date value using NLS settings; sometimes it succeeds, sometimes not. Therefore, you should always use dates and not rely on possible conversion success.
    • imagine you compared dateofstart to '01/02/03'; what is 01? Is it day (could be)? Month (could be as well)? Year (sure, why not)? But, if you used
      • date literal, which is always in format yyyy-mm-dd, e.g. date '2001-03-02', everyone (Oracle included) would know that it is 2nd of March 2001
      • TO_DATE функция, например. to_date('01/02/03', 'yy/dd/mm')
  • поскольку ваш столбец содержит дату и время, вы получите некоторые строки, только если значение dateofstart было сохранено ровно в полночь в начале этого дня. Если нет, либо

    • "remove" time component, e.g. where trunc(dateofstart) = date '2020-05-04' (which would make use of index (if it existed) on the dateofstart column unusable, unless you create a function-based index), or
    • используйте between, например.

      where dateofstart between to_date('04.05.2020 00:00:00', 'dd.mm.yyyy hh24:mi:ss') 
                            and to_date('04.05.2020 23:59:59', 'dd.mm.yyyy hh24:mi:ss')
      

Ваша вторая попытка неверна (лишняя одинарная кавычка, 010 (что это?)).

Третий вариант может работать, если Oracle распознает используемый вами формат.


Если вышеописанное не помогло, пожалуйста, опубликуйте тестовый пример (create table и insert into несколько примеров записей) (отредактируйте исходное сообщение, которое вы написали), чтобы мы могли увидеть, что вы сделали.

person Littlefoot    schedule 06.05.2020

Поскольку вы не можете точно сопоставить время, которое вы вставили, вам следует обрезать дату:

where trunc(dateofstart) = '04-MAY-20';
person J. Chomel    schedule 06.05.2020

Я настоятельно рекомендую вам НЕ использовать between с датами, особенно в Oracle, где у них есть компоненты времени. Самый простой метод, безопасный для индекса:

where dateofstart >= date '2020-05-10' and
      dateofstart < date '2020-06-16' + interval '1' day

Этот:

  • читается
  • использует стандартные литералы даты
  • не требует добавления компонента времени к датам сравнения
  • работает с компонентом времени или без него на dateofstart
  • безопасен для индекса.
person Gordon Linoff    schedule 06.05.2020