Oracle sqlSubtract между двумя датами - PullRequest
0 голосов
/ 20 марта 2012

Мне нужна помощь для написания запроса: выполните вычитание между двумя столбцами (дата начала и дата окончания), и обратите внимание, что тип столбцов: char , а не date , это точный формат: 10-MAR-12 11.11.40.288389000 AM ), затем получите среднее значение для результата.

Ответы [ 2 ]

1 голос
/ 20 марта 2012

Я предполагаю, что это домашняя работа, поэтому некоторые подсказки ...

Во-первых, никогда не храните даты как varchar, это вызовет у вас и оптимизатора всевозможные проблемы.

Во-вторых, тип данных Oracle date может сохранять только с точностью до секунды, а ваша строка имеет доли секунды, поэтому вы смотрите timestamp вместо date.Вы можете преобразовать вашу строку в метку времени с помощью функции to_timestamp(), передав подходящую маску формата .О, хорошо, я чувствую себя щедрым:

select to_timestamp(start_date, 'DD-Mon-RR HH.MI.SS.FF9 AM') from your_table;

В-третьих, вычитание двух временных меток даст вам тип данных interval, из которого вам потребуется извлечь нужную информацию.в читаемом формате.Поищите метку времени на этом сайте или в другом месте, но я укажу вам этот последний в качестве образца.

Среднее значение немного сложнее, поэтому вы можете захотеть преобразовать свои интервалына номера для этого;снова найдите предыдущие вопросы, такие как , этот .Размер интервалов, точность, которая вас действительно волнует, и способ форматирования выходных данных и т. Д. Будут иметь отношение к подходу, который вы хотите использовать.


Если вам нужен приблизительныйрезультат, то ответ @Joachim Isaksson даст вам это - «приблизительный» из-за округления;например, продолжительность меньше секунды будет отображаться как ноль.Тот же эффект можно увидеть с метками времени, приведенными к датам, которые также теряют доли секунды:

select 24*60*60*avg(
    cast(to_timestamp(step_ending_time, 'DD-Mon-RR HH.MI.SS.FF9 AM') as date)
        - cast(to_timestamp(step_starting_time, 'DD-Mon-RR HH.MI.SS.FF9 AM') as date)
    ) as avg_duration
from process_audit;

Более точный ответ можно найти, извлекая различные компоненты меток времени, как в вопросе, который я связал.раньше.Они могут вам не понадобиться, если вы знаете, что ваши длительности всегда меньше, скажем, часа, но если вам нужно больше одного (т. Е. Если продолжительность может быть больше минуты), то использование промежуточного общего табличного выражения упрощаетбит:

with cte as (
    select to_timestamp(step_ending_time, 'DD-Mon-RR HH.MI.SS.FF9 AM')
        - to_timestamp(step_starting_time, 'DD-Mon-RR HH.MI.SS.FF9 AM') as duration
    from process_audit
)
select avg(extract(second from duration)
    + extract(minute from duration) * 60
    + extract(hour from duration) * 60 * 60
    + extract(day from duration) * 60 * 60 * 24) as avg_duration
from cte;

С двумя строками выборки, одна с интервалом ровно в секунду, а другая с ровно 1,5 секундами, это дает результат 1.25.

0 голосов
/ 20 марта 2012

Комментарии о времени хранения в VARCHAR в стороне; Оракул to_date на помощь; это должно работать для вас, чтобы показать среднее количество секунд между временами. Поскольку у вас мало информации о точности, я не стал беспокоиться о «второстепенных секундах»;

SELECT 24*3600*AVG(
  to_date(enddate,   'DD-Mon-YY HH.Mi.SS.????????? AM') -
  to_date(startdate, 'DD-Mon-YY HH.Mi.SS.????????? AM')) avg_seconds
FROM TableA;

Демо здесь .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...