SQL.RU
 client/server technologies
Peoplemind  
 Главная | Документация | Статьи | Книги | Форум | Опросы | Рассылка | Работа | Поиск | FAQ |

Добро пожаловать в форум, Guest  >>  Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Oracle Новый топик  Ответить
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
 EXTRACT (second FROM interval) day to second   [new]
US Blast
Member

Откуда:
Сообщений: 14
Задача:
вычислить интервал между датами в секундах.

ВАРИАНТ №1
SQL> select (to_date('2008-07-15 15:22:01')-to_date('2005-06-15 15:22:01'))*86400 "interval (s)" from dual;

interval (s)
------------
97286400

ВАРИАНТ №2
SQL> select EXTRACT(second FROM (to_date('2008-07-15 15:22:01')-to_date('2005-06-15 15:22:01')) day to second) "interval (s)" from dual;

interval (s)
------------
0

Почему ВАРИАНТ №2 вернул ноль ?
Как используя "interval" вычислить интервал между датами в секундах?
4 июл 08, 18:04    [5889287] Ответить | Цитировать    Сообщить модератору

 Re: EXTRACT (second FROM interval) day to second   [new]
US Blast
Member

Откуда:
Сообщений: 14
совсем забыл...
ВАРИАНТ№3 НЕ ПРЕДЛАГАТЬ
SQL> select
2 EXTRACT(second FROM (to_date('2008-07-15 15:22:01')-to_date('2005-06-15 15:22:01')) day to second)
3 +
4 EXTRACT(minute FROM (to_date('2008-07-15 15:22:01')-to_date('2005-06-15 15:22:01')) day to second)*60
5 +
6 EXTRACT(hour FROM (to_date('2008-07-15 15:22:01')-to_date('2005-06-15 15:22:01')) day to second)*3600
7 +
8 EXTRACT(day FROM (to_date('2008-07-15 15:22:01')-to_date('2005-06-15 15:22:01')) day to second)*86400
9 "interval (s)" from dual;

interval (s)
------------
97286400

SQL>
4 июл 08, 18:11    [5889325] Ответить | Цитировать    Сообщить модератору

 Re: EXTRACT (second FROM interval) day to second   [new]
stax..
Guest
US Blast
Задача:
вычислить интервал между датами в секундах.

ВАРИАНТ №1
SQL> select (to_date('2008-07-15 15:22:01')-to_date('2005-06-15 15:22:01'))*86400 "interval (s)" from dual;

interval (s)
------------
97286400

ВАРИАНТ №2
SQL> select EXTRACT(second FROM (to_date('2008-07-15 15:22:01')-to_date('2005-06-15 15:22:01')) day to second) "interval (s)" from dual;

interval (s)
------------
0

Почему ВАРИАНТ №2 вернул ноль ?
Как используя "interval" вычислить интервал между датами в секундах?

я в етих новых фичах не очень
но вроде фигня какая-то
и у меня почемуто год не екстрактает

  1  select
  2  EXTRACT(YEAR FROM
  3  (
  4   (to_date('2008-07-15 15:23:02','yyyy-mm-dd hh24:mi:ss')
  5  -to_date('2005-08-15 15:22:01','yyyy-mm-dd hh24:mi:ss'))
  6* day to second)) "interval (s)" from dual
SQL> /
-to_date('2005-08-15 15:22:01','yyyy-mm-dd hh24:mi:ss'))
*
ERROR at line 5:
ORA-30076: неверное поле выборки для источника выборки
.....
stax
4 июл 08, 18:55    [5889561] Ответить | Цитировать    Сообщить модератору

 Re: EXTRACT (second FROM interval) day to second   [new]
SY
Member

Откуда: Middlebury, CT USA
Сообщений: 4773
US Blast
Почему ВАРИАНТ №2 вернул ноль ?
Как используя "interval" вычислить интервал между датами в секундах?


Well, you misunderstand EXTRACT. it does not convert interval to specified unit, It extracts (that is why it is called EXTRACT) specified unit from it. Now to_date('2008-07-15 15:22:01')-to_date('2005-06-15 15:22:01' is an interval of 1126 days 0 minutes 0 seconds and you ask to exctract seconds, so what else did you expect? Как используя "interval" вычислить? Something like:

SQL> SELECT  ((TRUNC(SYSDATE) + day_to_second_interval) - TRUNC(SYSDATE)) * 86400 sec
  2    FROM  (
  3           SELECT  numtodsinterval((to_date('2008-07-15 15:22:01')-to_date('2005-06-15 15:22:01')),'DAY') day_to_second_interval
  4             FROM  DUAL
  5          )
  6  /

       SEC
----------
  97286400

SQL> 

SY.
P.S. Keep in mind the above method will lose fractional part of a second stored in the interval.
4 июл 08, 20:02    [5889752] Ответить | Цитировать    Сообщить модератору

 Re: EXTRACT (second FROM interval) day to second   [new]
semirax
Member

Откуда:
Сообщений: 390
Не забудьте про то, что при переходе на летнее-зимнее время количество секунд не должно прыгать вверх/вниз на 3600:) Так что приведенный вариант не пойдет
6 июл 08, 15:47    [5892716] Ответить | Цитировать    Сообщить модератору

 Re: EXTRACT (second FROM interval) day to second   [new]
semirax
Member

Откуда:
Сообщений: 390
Вообще, любые конструкции, берущие только разность дат, будут работать некорректно, поскольку разность дат берется всегда в одном часовом поясе. Если же между датами был переход на летнее/зимнее время, то и пояс поменяется.

Вот пример функции, возвращающей количество секунд от 1 января 1970 года по гринвичу до указанной даты в временной зоны Москвы, которая учитывает летнее/зимнее время:

CREATE OR REPLACE FUNCTION unixtime(x DATE) 
return number as
begin
return (x - to_date('01011970','ddmmyyyy'))*24*60*60
-extract(TIMEZONE_HOUR from FROM_TZ(cast(x as timestamp),'Europe/Moscow'))*3600;
end;

select unixtime(to_date('2008-07-15 15:22:01','YYYY-MM-DD HH24:MI:SS')) 
-unixtime(to_date('2005-06-15 15:22:01','YYYY-MM-DD HH24:MI:SS')) from dual;
97286400
6 июл 08, 16:19    [5892783] Ответить | Цитировать    Сообщить модератору

 Re: EXTRACT (second FROM interval) day to second   [new]
US Blast
Member

Откуда:
Сообщений: 14
Всем спасибо.....
Но всё равно не понятно почему EXTRACT количество дней извлекает, а секунды нет.....
SQL> select
2 EXTRACT(second FROM (to_date('2008-07-13 17:48:34')
3 -to_date('2005-06-15 15:22:01')) day to second) "interval (s)" from dual;

interval (s)
------------
33

SQL>

получается эта зараза даёт разницу между датами как-то хитро ...
SQL> select
2 EXTRACT(YEAR FROM (to_date('2008-07-13 17:48:34')-to_date('2005-06-15 15:22:01')) YEAR to month) YEAR,
3 EXTRACT(month FROM (to_date('2008-07-13 17:48:34')-to_date('2005-06-15 15:22:01')) YEAR to month) month,
4 EXTRACT(day FROM (to_date('2008-07-13 17:48:34')-to_date('2005-06-15 15:22:01')) day to second) days,
5 EXTRACT(hour FROM (to_date('2008-07-13 17:48:34')-to_date('2005-06-15 15:22:01')) day to second) hour,
6 EXTRACT(minute FROM (to_date('2008-07-13 17:48:34')-to_date('2005-06-15 15:22:01')) day to second) minute,
7 EXTRACT(second FROM (to_date('2008-07-13 17:48:34')-to_date('2005-06-15 15:22:01')) day to second) second
8 from dual;

YEAR MONTH DAYS HOUR MINUTE SECOND
---------- ---------- ---------- ---------- ---------- ----------
3 1 1124 2 26 33

SQL>

прошу обратить внимание на колонку DAYS !!!!
7 июл 08, 10:52    [5894607] Ответить | Цитировать    Сообщить модератору

 Re: EXTRACT (second FROM interval) day to second   [new]
Elic
Member

Откуда: Минск
Сообщений: 19285
US Blast
Но всё равно не понятно почему EXTRACT количество дней извлекает, а секунды нет.....
 day to second
Потому что, день - это наивысшая единица измерения в интервале day to second.
7 июл 08, 11:00    [5894667] Ответить | Цитировать    Сообщить модератору

 Re: EXTRACT (second FROM interval) day to second   [new]
US Blast
Member

Откуда:
Сообщений: 14
INTERVAL DAY TO SECOND stores a period of time in terms of days, hours, minutes, and seconds. This datatype is useful for representing the precise difference between two datetime values.

Потому что, день - это наивысшая единица измерения в интервале day to second ????? Это почему?
7 июл 08, 11:23    [5894896] Ответить | Цитировать    Сообщить модератору

 Re: EXTRACT (second FROM interval) day to second   [new]
Elic
Member

Откуда: Минск
Сообщений: 19285
US Blast
INTERVAL DAY TO SECOND stores a period of time in terms of days, hours, minutes, and seconds. This datatype is useful for representing the precise difference between two datetime values.
Elic
Потому что, день - это наивысшая единица измерения в интервале day to second
????? Это почему?
Пора включить мозг.
7 июл 08, 11:37    [5895051] Ответить | Цитировать    Сообщить модератору

 Re: EXTRACT (second FROM interval) day to second   [new]
orawish
Member

Откуда: Гадюкино-2 (City)
Сообщений: 7559
US Blast
Всем спасибо.....
Но всё равно не понятно почему EXTRACT количество дней извлекает, а секунды нет.....

считаем вслух: Мальвина взяла у Буратины 3 рубля 15 копеек.
Екстракт от тоё копеек: пятнадцать
Екстракт от тоё рублей: три
7 июл 08, 13:08    [5895902] Ответить | Цитировать    Сообщить модератору

 Re: EXTRACT (second FROM interval) day to second   [new]
US Blast
Member

Откуда:
Сообщений: 14
да extract скажет что копеек 15....
но на самом деле копеек 3*100+15, а вот рубля всего 3........
да ладно будем считать как есть , но логига какая-то странная.......
хотя....
7 июл 08, 13:20    [5896016] Ответить | Цитировать    Сообщить модератору

 Re: EXTRACT (second FROM interval) day to second   [new]
orawish
Member

Откуда: Гадюкино-2 (City)
Сообщений: 7559
US Blast
да extract скажет что копеек 15....
но на самом деле копеек 3*100+15, а вот рубля всего 3........
да ладно будем считать как есть , но логига какая-то странная.......
хотя....

просто это - совсем не экстракт а сумма экстрактов с масштабным коэффициентом при каждом
7 июл 08, 13:54    [5896283] Ответить | Цитировать    Сообщить модератору

 Re: EXTRACT (second FROM interval) day to second   [new]
semirax
Member

Откуда:
Сообщений: 390
Раз уж зашла речь о функции extract.. поделюсь интересным моментом

Возьмем такой запрос:
select extract(month from ((sysdate+15-sysdate) year to month)) "month" from dual;

Результат: 1
Кажется, что от значения sysdate такой запрос не должен зависеть, а только от разности дат, которая есть 15 дней.

Для проверки подставим вместо sysdate выражение вида sysdate+10

select extract(month from (((sysdate+10)+15-(sysdate+10)) year to month)) "month" from dual;

Результат: 0

И вот еще второй глюк:
Все считают, что разности двух типов DATE дает тип NUMBER.
Попробуем такое:

select cast((sysdate+1-sysdate) as interval year to month) from dual;

Получим ошибку:
ORA-00932: несовместимые типы данных: ожидается INTERVAL YEAR TO MONTH,
получено DATE JULIAN


Что за тип такой - DATE JULIAN? Недокументированный что ли?
7 июл 08, 14:04    [5896358] Ответить | Цитировать    Сообщить модератору

 Re: EXTRACT (second FROM interval) day to second   [new]
US Blast
Member

Откуда:
Сообщений: 14
вообщем остановился на таком аврианте...
select
(to_date('2008-10-26 17:48:34') -to_date('2008-10-25 17:48:34'))*86400
+
(extract(TIMEZONE_HOUR from FROM_TZ(cast(to_date('2008-10-25 17:48:34') as timestamp),'Europe/Kiev'))-
extract(TIMEZONE_HOUR from FROM_TZ(cast(to_date('2008-10-26 17:48:34') as timestamp),'Europe/Kiev'))
)*3600 from dual;

select
(to_date('2008-03-30 17:48:34') -to_date('2008-03-29 17:48:34'))*86400
+
(extract(TIMEZONE_HOUR from FROM_TZ(cast(to_date('2008-03-29 17:48:34') as timestamp),'Europe/Kiev'))-
extract(TIMEZONE_HOUR from FROM_TZ(cast(to_date('2008-03-30 17:48:34') as timestamp),'Europe/Kiev'))
)*3600 from dual;
7 июл 08, 14:10    [5896417] Ответить | Цитировать    Сообщить модератору

 Re: EXTRACT (second FROM interval) day to second   [new]
semirax
Member

Откуда:
Сообщений: 390
и вот еще: не ко всем датам можно прибавлять все интервалы.

Попробуйте такое:
select to_date('30-01-2008','dd-mm-yyyy')+interval '00-01' year to month from dual;

Получите ORA-01839
7 июл 08, 14:16    [5896481] Ответить | Цитировать    Сообщить модератору

 Re: EXTRACT (second FROM interval) day to second   [new]
US Blast
Member

Откуда:
Сообщений: 14
SQL> select extract(day from ((sysdate+15-sysdate) day to second )) "day" from dual;

day
----------
15
7 июл 08, 14:16    [5896486] Ответить | Цитировать    Сообщить модератору

 Re: EXTRACT (second FROM interval) day to second   [new]
orawish
Member

Откуда: Гадюкино-2 (City)
Сообщений: 7559
semirax
Раз уж зашла речь о функции extract.. поделюсь интересным моментом

Возьмем такой запрос:
select extract(month from ((sysdate+15-sysdate) year to month)) "month" from dual;

Результат: 1
Кажется, что от значения sysdate такой запрос не должен зависеть, а только от разности дат, которая есть 15 дней.

Для проверки подставим вместо sysdate выражение вида sysdate+10

select extract(month from (((sysdate+10)+15-(sysdate+10)) year to month)) "month" from dual;

Результат: 0

И вот еще второй глюк:
Все считают, что разности двух типов DATE дает тип NUMBER.
Попробуем такое:

select cast((sysdate+1-sysdate) as interval year to month) from dual;

Получим ошибку:
ORA-00932: несовместимые типы данных: ожидается INTERVAL YEAR TO MONTH,
получено DATE JULIAN


Что за тип такой - DATE JULIAN? Недокументированный что ли?

это не баг (если подумать ;) Разве что - сообщение ругательное могло быть поконкретнее.

Вы спросили: сколько ЛЕТ(МЕСЯЦЕВ) в одном дне - сервер вам честно сказал: х.. его знает.
Логичный ответ. Он же годен и как ответ на вопрос: сколько метров в килограмме.
Разве же не очевидно, что M-Y и D-S разные, ни разу не_переводимые друг в друга интервалы?
7 июл 08, 14:24    [5896550] Ответить | Цитировать    Сообщить модератору

 Re: EXTRACT (second FROM interval) day to second   [new]
semirax
Member

Откуда:
Сообщений: 390
Логичней было бы если бы сервер всегда ругался на преобразование D_S в Y_M.
Либо использовал конкретное значение вида "месяц - это ровно 30 дней" и считал как следствие что в 1 дне 0 месяцев.

А так получается что функция extract "слегка" недетерминировано себя ведет.
7 июл 08, 14:32    [5896619] Ответить | Цитировать    Сообщить модератору

 Re: EXTRACT (second FROM interval) day to second   [new]
Elic
Member

Откуда: Минск
Сообщений: 19285
semirax
Попробуем cast((sysdate+1-sysdate) as interval year to month)
RTFM Casting Built-In Datatypes: from NUMBER to INTERVAL (FAQ)
semirax
Что за тип такой - DATE JULIAN?
select to_date(1e7-1, 'j') from dual;


orawish
Вы спросили: сколько ЛЕТ(МЕСЯЦЕВ) в одном дне - сервер вам честно сказал: х.. его знает.
Не то :) (сравни с "а сколько дней(секунд)?")
7 июл 08, 14:34    [5896633] Ответить | Цитировать    Сообщить модератору

 Re: EXTRACT (second FROM interval) day to second   [new]
US Blast
Member

Откуда:
Сообщений: 14
чего-то не хочет :-(
SQL> select cast((to_date('2008-10-26 17:48:34')-to_date('2008-10-25 17:48:34')) as INTERVAL DAY TO SECOND) from dual;
select cast((to_date('2008-10-26 17:48:34')-to_date('2008-10-25 17:48:34')) as INTERVAL DAY TO SECOND) from dual
*
ERROR at line 1:
ORA-00932: inconsistent datatypes: expected INTERVAL got DATE


SQL>
7 июл 08, 14:38    [5896673] Ответить | Цитировать    Сообщить модератору

 Re: EXTRACT (second FROM interval) day to second   [new]
orawish
Member

Откуда: Гадюкино-2 (City)
Сообщений: 7559
semirax
Логичней было бы если бы сервер всегда ругался на преобразование D_S в Y_M.
Либо использовал конкретное значение вида "месяц - это ровно 30 дней" и считал как следствие что в 1 дне 0 месяцев.

А так получается что функция extract "слегка" недетерминировано себя ведет.

имхо, тот кто её ваял, предполагал, что пользоваться ею будут по-назначению..
А если виноватых искать - так это к цезарям, которые оставили такой календарь ну и к тому, кто забебенил планете траекторию
7 июл 08, 14:40    [5896690] Ответить | Цитировать    Сообщить модератору

 Re: EXTRACT (second FROM interval) day to second   [new]
US Blast
Member

Откуда:
Сообщений: 14
мдя ...учиться и учиться ....ктоб мог подумать...
SQL> select cast(
2 (sysdate+10-sysdate)*86400*interval '1'second as INTERVAL DAY TO SECOND) from dual;

CAST((SYSDATE+10-SYSDATE)*86400*INTERVAL'1'SECONDASINTERVALDAYTOSECOND)
---------------------------------------------------------------------------
+10 00:00:00.000000

SQL>
всё просто как два байта переслать :-)
7 июл 08, 14:59    [5896856] Ответить | Цитировать    Сообщить модератору

 Re: EXTRACT (second FROM interval) day to second   [new]
Elic
Member

Откуда: Минск
Сообщений: 19285
US Blast
cast((sysdate+10-sysdate)*86400*interval '1'second  as INTERVAL DAY TO SECOND)
Северный варвар
numtodsinterval(sysdate+10-sysdate, 'day')
7 июл 08, 15:07    [5896921] Ответить | Цитировать    Сообщить модератору

 Re: EXTRACT (second FROM interval) day to second   [new]
semirax
Member

Откуда:
Сообщений: 390
(sysdate+10-sysdate)*86400*interval '1' second

Перемножение интервалов времени... где траву такую хорошую берешь?:)
7 июл 08, 15:07    [5896926] Ответить | Цитировать    Сообщить модератору

Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Oracle Ответить
Rambler's Top100 Powered by ActualForum 1.5.2 Copyright (c) Alex Sibilev 2000-2010