theskiguy Ответов: 1

Как суммировать столбец в oracle 9, чтобы включить часть первой и последней строки и полное количество оставшихся строк


Это довольно трудно объяснить. Я пытаюсь суммировать целочисленный столбец на основе столбца даты. Проблема в том, что данные в моем столбце даты редко точно совпадают с моим предложением where, поэтому мне нужно изменить результаты только первой и последней строк. Вот некоторые примеры данных:

Вывод,Машина,Статус,DownTimeCode,Продолжительность

15.06.2017 05:50: 00 AM, 500, 2, null, 60
06/15/2017 06:01:00 утра,500,3,10,660
15.06.2017 06: 03: 00 AM, 500, 2, null, 120
15.06.2017 06: 04: 00 AM, 500, 3, 12, 60
15.06.2017 07:01: 00 AM, 500, 3, 13, 3420

Сначала позвольте мне кратко объяснить данные:
Столбец LogTime содержит время регистрации события в базе данных, которое находится в конце каждого события. Столбец длительность содержит время в секундах, в течение которого длилось событие. Таким образом, для первого ряда событие закончилось в 5:50:00 утра, а продолжительность 60 секунд означает, что событие началось в 5:49:00 утра.

Что я уже пробовал:

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

Например:
Выберите сумму (продолжительность)
Из Machines_Log
Где машина = '500'
и logtime > TO_DATE ('15.06.2017 06: 00: 00 AM', 'MM/DD/YYYY HH:MI:SS AM')
и logtime <= TO_DATE ('15.06.2017 07: 00: 00 AM', 'MM/DD/YYYY HH:MI:SS AM')
и статус = 3

Это вернет (660+60) = 720
Однако этот ответ-не то, что мне нужно. 660 секунд содержат 600 секунд времени до 6: 00: 00 и 60 секунд после 6:00: 00. Меня интересуют только 60 секунд после этого. То же самое происходит и в последнем ряду. Мне нужна та часть 3420 секунд, которая будет до 7:00:00 утра. В этом случае я хочу только (3420-60) = 3360 секунд. Таким образом, моя сумма должна составить 60+60+3360 = 3480

В настоящее время я делаю это с несколькими запросами через VB.net считыватель данных, где я читаю каждую строку одну за другой. Если это первая строка, я настраиваю продолжительность на основе времени регистрации и даты начала в моем предложении Where. Когда я получаю последнюю строку, я запускаю 2-й запрос, чтобы найти следующую строку, которая имеет logtime больше, чем последнее logtime, которое я прочитал с помощью моего datareader. Затем я беру только часть продолжительности из этого результата, основанного на дате окончания в моем предложении where. Я уверен, что должен быть лучший и более эффективный способ сделать это, но мои знания SQL ограничены только базовыми запросами.

1 Ответов

Рейтинг:
7

RAMASWAMY EKAMBARAM

with dtrange as
(
select to_date('15-jun-2017 06:00', 'dd-mon-yyyy hh24:mi') range_start,  to_date('15-jun-2017 07:00', 'dd-mon-yyyy hh24:mi') range_end
from dual
),
recs_in_range as
(
select greatest(range_start, downstart) downstart, least(downend, range_end) downend
from
(
select (logtime - duration / 86400) downstart, logtime downend,  range_start, range_end
from machines_log, dtrange
where machine = '500'
and status = 3
and not (logtime < range_start
or (logtime - duration / 86400) > range_end)
)
)
select round(sum((downend - downstart) * 86400))
from recs_in_range
-- 86400 == 24 * 60 * 60 i.e. no of seconds in a day
-- 


theskiguy

Именно то, что мне было нужно. Спасибо