Запрос Oracle SQL с двумя фильтрами дат не возвращает значение

#sql #oracle

#sql #Oracle

Вопрос:

У меня есть эта таблица в oracle :

 CREATE TABLE "MY_FOO"."SG_MEM" 
   (    "SG_MEM_OBJ" NUMBER, 
    "SG_OBJ_NUM" NUMBER, 
    "SUB_NUM" NUMBER, 
    "F_DATE" DATE, 
    "X_DATE" DATE
   }
  

затем я вставляю исходные данные :

 insert into SG_MEM  (  SG_MEM_OBJ ,
                        SG_OBJ_NUM , 
                        SUB_NUM ,
                        F_DATE , 
                        X_DATE  ) 
            values  (
                        24242,
                        33333,
                        2001936,
                        SYSDATE,
                        TO_DATE('2019/10/19 10:43:12', 'yyyy/mm/dd HH:MI:SS'));
  

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

 INSERT
INTO EXPORT_TABLE
  (
    SG_MEM_OBJ ,
    SG_OBJ_NUM,
    SUB_NUM ,
    F_DATE ,
    X_DATE
  )
  VALUES
  (
    24242,33333,2001936,
    to_date('20-October-2016','DD-MON-RRRR'),
    to_date('19-October-2019','DD-MON-RRRR')
  ); 
  

Теперь моя проблема в том, что я пытаюсь извлечь эти данные следующим образом :

 select SG_MEM_OBJ ,
                  SG_OBJ_NUM ,
                  SUB_NUM ,
                  F_DATE ,
                  X_DATE  
 from SG_MEM  
 where  SG_MEM_OBJ =2001936 
and F_DATE  <=  TO_DATE('16/10/24 8:10:12', 'yyyy/mm/dd HH:MI:SS')
and X_DATE  > TO_DATE('16/10/24 8:10:12', 'yyyy/mm/dd HH:MI:SS');    
  

Он не извлекает единственную запись, если я прокомментирую эту строку :

  and F_DATE  <=  TO_DATE('16/10/24 8:10:12', 'yyyy/mm/dd HH:MI:SS')     
  

он извлекает его.
Я не вижу здесь проблемы.

Комментарии:

1. Что ж, дата 20 октября, которая у вас там есть, позже (читай: больше), чем дата 16 октября в вашем where clayse…

2. спасибо, я перепутал даты…

3. '16/10/24 8:10:12' не соответствует шаблону: 'yyyy/mm/dd HH:MI:SS'

Ответ №1:

Даже при внешне согласованных датах способ преобразования строки в даты — особенно в вашем конечном запросе — неправильный. Например, когда вы делаете:

 and F_DATE  <=  TO_DATE('16/10/24 8:10:12', 'yyyy/mm/dd HH:MI:SS')
  

Вы не получаете ожидаемую дату. Вы передаете двузначный год с 4-значной маской года в модели format; вы можете увидеть, что это на самом деле дает с помощью:

 alter session set nls_date_format = 'SYYYY-MM-DD HH24:MI:SS';
select TO_DATE('16/10/24 8:10:12', 'yyyy/mm/dd HH:MI:SS') from dual;

TO_DATE('16/10/248:1
--------------------
 0016-10-24 08:10:12
  

Таким образом, вы ищете значения до 0016 года, а не до 2016. Вы должны делать:

 and F_DATE  <=  TO_DATE('2016/10/24 8:10:12', 'yyyy/mm/dd HH24:MI:SS')
  

Вероятно, вам также следует использовать HH24 вместо HH , поэтому я использовал это. Все ваши значения времени в данный момент будут равны AM, что может быть тем, что вы хотите здесь, но все же лучше указывать явно.

Вместо этого вы могли бы использовать литерал временной метки ANSI (приведенный к дате, если столбец проиндексирован), если значение, по которому вы ищете, является фиксированным. Вы могли бы также использовать двузначные годы в своей строке, если вы используете RR модель для года вместо YYYY или YY ; но все же лучше использовать четырехзначные годы, чтобы избежать возможной путаницы.