Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Oracle Новый топик    Ответить
 to_date без даты и сравнение по времени  [new]
Kido
Member

Откуда:
Сообщений: 46
В таблице 2 поля с типом date в которых хранится время: start_time, end_time

Нужно получать строки, у которых промежуток между start_time и end_time соответсвтует sysdate
Приложение по умолчанию садит дату 01.01.1980. Расчитывать, что она всегда будет такой я не могу (кто знает, что там поменяется).
Моё первое решение выглядит следующим образом:
with t as (
  select to_date('01.01.1980 09:00:00','dd.mm.yyyy hh24:mi:ss') as start_time, to_date('01.01.1980 15:00:00','dd.mm.yyyy hh24:mi:ss') as end_time from dual union all 
  select to_date('01.01.1980 15:00:00','dd.mm.yyyy hh24:mi:ss') as start_time, to_date('01.01.1980 21:00:00','dd.mm.yyyy hh24:mi:ss') as end_time from dual union all 
  select to_date('01.01.1980 12:00:00','dd.mm.yyyy hh24:mi:ss') as start_time, to_date('01.01.1980 22:00:00','dd.mm.yyyy hh24:mi:ss') as end_time from dual union all 
  select to_date('01.01.1980 18:00:00','dd.mm.yyyy hh24:mi:ss') as start_time, to_date('01.01.1980 23:00:00','dd.mm.yyyy hh24:mi:ss') as end_time from dual  
)
  select * from t 
  where 
    to_char(sysdate,'hh24:mi:ss')
      between 
        to_char(start_time, 'hh24:mi:ss')
        and 
        to_char(end_time, 'hh24:mi:ss') ;


Но ведь это сравнение строк, а не дат. Мне почему то показалось, что это не верно и потому второй вариант выглядит уже вот так
with t as (
  select to_date('01.01.1980 09:00:00','dd.mm.yyyy hh24:mi:ss') as start_time, to_date('01.01.1980 15:00:00','dd.mm.yyyy hh24:mi:ss') as end_time from dual union all 
  select to_date('01.01.1980 15:00:00','dd.mm.yyyy hh24:mi:ss') as start_time, to_date('01.01.1980 21:00:00','dd.mm.yyyy hh24:mi:ss') as end_time from dual union all 
  select to_date('01.01.1980 12:00:00','dd.mm.yyyy hh24:mi:ss') as start_time, to_date('01.01.1980 22:00:00','dd.mm.yyyy hh24:mi:ss') as end_time from dual union all 
  select to_date('01.01.1980 18:00:00','dd.mm.yyyy hh24:mi:ss') as start_time, to_date('01.01.1980 23:00:00','dd.mm.yyyy hh24:mi:ss') as end_time from dual  
)
  select * from t 
  where 
    to_date(to_char(sysdate,'hh24:mi:ss'),'hh24:mi:ss') 
      between 
        to_date(to_char(start_time, 'hh24:mi:ss'),'hh24:mi:ss') 
        and 
        to_date(to_char(end_time, 'hh24:mi:ss'),'hh24:mi:ss') ;
        


И отсюда вытекает второй вопрос - почему оракл когда делаешь
SQL> select to_date('10:00:00','hh24:mi:ss') from dual; 

TO_DATE('10:00:00','HH24:MI:SS')
--------------------------------
01.10.2017 10:00:00 
выбирает дату равную 1 числа, текущего месяца. Можно ли на это пологаться. В доке ответа не нашел. Ткните если кто найдет пож-та.

Ну это уже побочный вопрос :)

Господа, хотелось бы услышать ваше мнение. Какой из подходов более адекватен или как бы вы решили эту задачу.
Спасибо
6 окт 17, 12:36    [20847860]     Ответить | Цитировать Сообщить модератору
 Re: to_date без даты и сравнение по времени  [new]
Stax
Member

Откуда: Ukraine,Lviv
Сообщений: 618
Kido,

в чем проблема со сравнением строк?
я б убрал разделители

https://docs.oracle.com/cd/B28359_01/server.111/b28286/sql_elements003.htm#SQLRF51049
автор
If you specify a date value without a date, then the default date is the first day of the current month.



.....
stax
6 окт 17, 12:47    [20847915]     Ответить | Цитировать Сообщить модератору
 Re: to_date без даты и сравнение по времени  [new]
AmKad
Member

Откуда:
Сообщений: 4689
with t as (
  select to_date('01.01.1980 09:00:00','dd.mm.yyyy hh24:mi:ss') as start_time, to_date('01.01.1980 15:00:00','dd.mm.yyyy hh24:mi:ss') as end_time from dual union all
  select to_date('01.01.1980 15:00:00','dd.mm.yyyy hh24:mi:ss') as start_time, to_date('01.01.1980 21:00:00','dd.mm.yyyy hh24:mi:ss') as end_time from dual union all
  select to_date('01.01.1980 12:00:00','dd.mm.yyyy hh24:mi:ss') as start_time, to_date('01.01.1980 22:00:00','dd.mm.yyyy hh24:mi:ss') as end_time from dual union all
  select to_date('01.01.1980 18:00:00','dd.mm.yyyy hh24:mi:ss') as start_time, to_date('01.01.1980 23:00:00','dd.mm.yyyy hh24:mi:ss') as end_time from dual
)
  select sysdate, t.*
  from t
  where numtodsinterval(sysdate - trunc(sysdate), 'day') between
                    numtodsinterval(start_time - trunc(start_time), 'day')
                and numtodsinterval(end_time   - trunc(end_time  ), 'day');

SYSDATE             START_TIME          END_TIME
------------------- ------------------- -------------------
2017-10-06 12:50:14 1980-01-01 09:00:00 1980-01-01 15:00:00
2017-10-06 12:50:14 1980-01-01 12:00:00 1980-01-01 22:00:00
6 окт 17, 12:50    [20847926]     Ответить | Цитировать Сообщить модератору
 Re: to_date без даты и сравнение по времени  [new]
AmKad
Member

Откуда:
Сообщений: 4689
AmKad,

where sysdate - trunc(sysdate) between start_time - trunc(start_time) and end_time - trunc(end_time)
6 окт 17, 12:52    [20847932]     Ответить | Цитировать Сообщить модератору
 Re: to_date без даты и сравнение по времени  [new]
Kido
Member

Откуда:
Сообщений: 46
AmKad, Stax

Больше спасибо!
6 окт 17, 13:29    [20848102]     Ответить | Цитировать Сообщить модератору
 Re: to_date без даты и сравнение по времени  [new]
Stax
Member

Откуда: Ukraine,Lviv
Сообщений: 618
Kido
Расчитывать, что она всегда будет такой я не могу (кто знает, что там поменяется).


подляна будет если старт и енд будут не в один день
напр через полночь (третья смена)


.....
stax
6 окт 17, 15:20    [20848700]     Ответить | Цитировать Сообщить модератору
 Re: to_date без даты и сравнение по времени  [new]
env
Member

Откуда: Россия, Москва
Сообщений: 5598
Kido
Приложение по умолчанию садит дату 01.01.1980

Kido
или как бы вы решили эту задачу.


Содрать с автора приложения неустойку за косячную дату и потребовать доработки под адекватные данные.
6 окт 17, 16:18    [20848864]     Ответить | Цитировать Сообщить модератору
 Re: to_date без даты и сравнение по времени  [new]
Fogel
Member

Откуда:
Сообщений: 267
Stax
Kido
Расчитывать, что она всегда будет такой я не могу (кто знает, что там поменяется).


подляна будет если старт и енд будут не в один день
напр через полночь (третья смена)


.....
stax

with t as (
  select to_date('01.01.1980 09:00:00','dd.mm.yyyy hh24:mi:ss') as start_time, to_date('01.01.1980 15:00:00','dd.mm.yyyy hh24:mi:ss') as end_time from dual union all
  select to_date('01.01.1980 15:00:00','dd.mm.yyyy hh24:mi:ss') as start_time, to_date('01.01.1980 21:00:00','dd.mm.yyyy hh24:mi:ss') as end_time from dual union all
  select to_date('01.01.1980 12:00:00','dd.mm.yyyy hh24:mi:ss') as start_time, to_date('01.01.1980 22:00:00','dd.mm.yyyy hh24:mi:ss') as end_time from dual union all
  select to_date('01.01.1980 18:00:00','dd.mm.yyyy hh24:mi:ss') as start_time, to_date('01.01.1980 23:00:00','dd.mm.yyyy hh24:mi:ss') as end_time from dual
)
 select sysdate, t.* from t where to_date(to_char(t.start_time,'dd.mm.yyyy')||' '||to_char(sysdate,'hh24:mi:ss'), 'dd.mm.yyyy hh24:mi:ss') between t.start_time and t.end_time
6 окт 17, 16:32    [20848928]     Ответить | Цитировать Сообщить модератору
 Re: to_date без даты и сравнение по времени  [new]
Stax
Member

Откуда: Ukraine,Lviv
Сообщений: 618
Fogel,
от постановщиков зависит как и что считать
with t as (
  select to_date('06.09.2017 23:00:00','dd.mm.yyyy hh24:mi:ss') as start_time, to_date('07.09.2017 07:00:00','dd.mm.yyyy hh24:mi:ss') as end_time from dual 
)
 select sysdat, t.* from t ,
 (select to_date('06.10.2017 01:00:00','dd.mm.yyyy hh24:mi:ss') sysdat from dual) --sysdate
where to_date(to_char(t.start_time,'dd.mm.yyyy')||' '||to_char(sysdat,'hh24:mi:ss'), 'dd.mm.yyyy hh24:mi:ss') between t.start_time and t.end_time
/

......
stax
6 окт 17, 16:56    [20849042]     Ответить | Цитировать Сообщить модератору
 Re: to_date без даты и сравнение по времени  [new]
Kido
Member

Откуда:
Сообщений: 46
env,

Автор приложения сам сдирает с нас немалые деньги. В обратную сторону этот механизм не работает :)
9 окт 17, 06:05    [20853328]     Ответить | Цитировать Сообщить модератору
Все форумы / Oracle Ответить