Как искать дату в запросе при использовании sysdate - PullRequest
1 голос
/ 06 мая 2020

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

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

where dateofstart = '04-MAY-20';

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

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

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

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

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

Ответы [ 3 ]

3 голосов
/ 06 мая 2020

Если вы использовали 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', вы сделали две ошибки:

  • вы сравниваете DATE столбец типа данных со строкой. Да, '04-MAY-20' - строка; это выглядит как для вас и меня, но для Oracle это просто строка. Oracle пытается неявно преобразовать его в значение даты, используя настройки NLS; иногда это удается, иногда нет. Поэтому вам следует всегда использовать даты и не полагаться на возможный успех преобразования.
    • представьте, что вы сравнили dateofstart с '01/02/03'; что такое 01? Это день (может быть)? Месяц (тоже может быть)? Год (конечно, а почему бы и нет)? Но, если вы использовали
      • литерал даты, который всегда имеет формат yyyy-mm-dd, например date '2001-03-02', все (включая Oracle) будут знать, что это 2 марта 2001 года
      • TO_DATE, например to_date('01/02/03', 'yy/dd/mm')
  • , поскольку ваш столбец содержит дату и время, вы Я бы получил несколько строк, только если бы dateofstart значение было сохранено ровно в полночь в начале этого дня. Если нет, либо

    • «удалить» компонент времени, например where trunc(dateofstart) = date '2020-05-04' (который будет использовать индекс (если он существует) в столбце dateofstart неиспользуемый , если только вы создаете индекс на основе функций) или
    • используйте 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 несколько примеров записей) (отредактируйте исходное сообщение, которое вы написали), чтобы мы могли увидеть, что вы сделали.

1 голос
/ 06 мая 2020

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

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

Это:

  • доступно для чтения
  • использует стандартные литералы даты
  • не требует добавления компонента времени к датам сравнения
  • работает с компонентом времени или без него на dateofstart
  • является индексно-безопасным.
1 голос
/ 06 мая 2020

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

where trunc(dateofstart) = '04-MAY-20';
...