Рассчитать сумму длительности в SQL-запрос - PullRequest
5 голосов
/ 21 мая 2009

У меня есть таблица, в которой есть два столбца: время начала и время окончания. Я могу рассчитать продолжительность времени для каждой строки, но я также хочу получить общую продолжительность. как это сделать.

Спасибо

Ответы [ 4 ]

19 голосов
/ 21 мая 2009

Ваши столбцы имеют тип данных TIMESTAMP, например:

SQL> create table mytable (start_time,end_time)
  2  as
  3  select to_timestamp('2009-05-01 12:34:56','yyyy-mm-dd hh24:mi:ss')
  4       , to_timestamp('2009-05-01 23:45:01','yyyy-mm-dd hh24:mi:ss')
  5    from dual
  6   union all
  7  select to_timestamp('2009-05-01 23:45:01','yyyy-mm-dd hh24:mi:ss')
  8       , to_timestamp('2009-05-02 01:23:45','yyyy-mm-dd hh24:mi:ss')
  9    from dual
 10   union all
 11  select to_timestamp('2009-05-01 07:00:00','yyyy-mm-dd hh24:mi:ss')
 12       , to_timestamp('2009-05-01 08:00:00','yyyy-mm-dd hh24:mi:ss')
 13    from dual
 14  /

Tabel is aangemaakt.

Вычитание одной временной метки из другой приводит к типу ИНТЕРВАЛ:

SQL> select start_time
  2       , end_time
  3       , end_time - start_time time_difference
  4    from mytable
  5  /

START_TIME                     END_TIME                       TIME_DIFFERENCE
------------------------------ ------------------------------ ------------------------------
01-05-09 12:34:56,000000000    01-05-09 23:45:01,000000000    +000000000 11:10:05.000000000
01-05-09 23:45:01,000000000    02-05-09 01:23:45,000000000    +000000000 01:38:44.000000000
01-05-09 07:00:00,000000000    01-05-09 08:00:00,000000000    +000000000 01:00:00.000000000

3 rijen zijn geselecteerd.

И типы данных INTERVAL нельзя суммировать. Это раздражающее ограничение:

SQL> select sum(end_time - start_time)
  2    from mytable
  3  /
select sum(end_time - start_time)
                    *
FOUT in regel 1:
.ORA-00932: inconsistente gegevenstypen: NUMBER verwacht, INTERVAL DAY TO SECOND gekregen

Чтобы обойти это ограничение, вы можете конвертировать и рассчитывать количество секунд, например:

SQL> select start_time
  2       , end_time
  3       , trunc(end_time) - trunc(start_time) days_difference
  4       , to_number(to_char(end_time,'sssss')) - to_number(to_char(start_time,'sssss')) seconds_difference
  5    from mytable
  6  /

START_TIME                     END_TIME                       DAYS_DIFFERENCE SECONDS_DIFFERENCE
------------------------------ ------------------------------ --------------- ------------------
01-05-09 12:34:56,000000000    01-05-09 23:45:01,000000000                  0              40205
01-05-09 23:45:01,000000000    02-05-09 01:23:45,000000000                  1             -80476
01-05-09 07:00:00,000000000    01-05-09 08:00:00,000000000                  0               3600

3 rijen zijn geselecteerd.

И тогда это нормальные числа, которые можно суммировать

SQL> select sum
  2         (  86400 * (trunc(end_time) - trunc(start_time))
  3          + to_number(to_char(end_time,'sssss')) - to_number(to_char(start_time,'sssss'))
  4         ) total_time_difference
  5    from mytable
  6  /

TOTAL_TIME_DIFFERENCE
---------------------
                49729

1 rij is geselecteerd.

А если хотите, вы можете преобразовать это число обратно в ИНТЕРВАЛ:

SQL> select numtodsinterval
  2         ( sum
  3           (  86400 * (trunc(end_time) - trunc(start_time))
  4            + to_number(to_char(end_time,'sssss')) - to_number(to_char(start_time,'sssss'))
  5           )
  6         , 'second'
  7         ) time_difference
  8    from mytable
  9  /

TIME_DIFFERENCE
------------------------------
+000000000 13:48:49.000000000

1 rij is geselecteerd.

С уважением, Роб.

2 голосов
/ 19 октября 2010

Этот метод для Oracle прост, хотя и немного взломан:

select sum((end_timestamp+0) - (start_timestamp+0)) 
from your_table

Результатом является КОЛИЧЕСТВО дней (с дробной частью часов, минут и вы знаете).

Я не знаю, что именно делает отметка времени + 0; возможно, отметка времени ANSI преобразуется в более ранний тип отметки времени Oracle, который допускает простую арифметику.

2 голосов
/ 21 мая 2009

РЕДАКТИРОВАТЬ: Добавлена ​​trunc () перед суммированием на основе превосходного ответа Роба ван Вейк.

Чтобы найти продолжительность в строке:

select 
    end_date-start_date as DurationDays, 
    (end_date-start_date)*24 as DurationHours, 
    (end_date-start_date)*24*60 as DurationMinutes, 
    (end_date-start_date)*24*60*60 as DurationSeconds
from your_table

Чтобы найти общую продолжительность:

select 
    sum(trunc(end_date-start_date)) as TotalDurationDays
from your_table

Чтобы сделать оба в одном запросе:

select 
    end_date-start_date as DurationDays, 
    (select sum(trunc(end_date-start_date)) from your_table) as TotalDurationDays
from your_table
1 голос
/ 21 мая 2009

Вы можете использовать этот запрос (он работает как минимум на БД Oracle):

select sum(end_date - start_date) from your_table
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...