2015-11-17 3 views
0

Мне нужно разбить каждую строку данных на уровне часа с учетом разницы в часах. я начинаю со следующими данными:Как я могу разбить строку данных на уровне часа?

enter image description here

и я хотел бы выводить этот результат:

enter image description here

Tally является количество раз, событие происходит в период между двумя датами, New_date будет началом каждого сегмента, а new_tally - делением первоначальной суммы, соответствующей пропорции времени для каждого сегмента.

Я попытался выполнения sqlfiddle в этом другом question, но я получаю следующее сообщение об ошибке:

ORA-01436: CONNECT BY loop in user data

Точный код с скрипкой:

create table log_table 
     (dt1 date, dt2 date 
     ); 

    insert into log_table values(sysdate,sysdate-5/24); 

    select greatest(dt2, trunc(dt2+(level-1)/24, 'hh24')), least(dt1, trunc(dt2+(level)/24, 'hh24')) 
    from log_table connect by level <= floor((dt1-dt2)*24)+1; 

Это, возможно, придется делать с тем фактом, что я пытаюсь это в Oracle 8i DB. Я также пытался понять, как работают иерархические запросы, но я нахожу их очень сложными.

Может ли кто-нибудь дать мне пример и объяснить, что происходит? Заранее спасибо.

Nega.

+0

Можете добавить код, который вы пробовали; или ссылку на Fiddle, на которую была получена ошибка, которая предположительно включает в себя вашу настройку данных и запрос? –

+0

Это скрипка http://sqlfiddle.com/#!4/82625/29. Это не мой код, хотя он и связан с вопросом. – Negashion

+0

Я не получаю ORA-01436 от этого Fiddle, так что я немного смущен. Я могу представить, как вы могли бы попытаться адаптировать его, но это поможет, если вы покажете фактический код, который вы используете. Я могу видеть, что ты дон; но почему вы не хотите new_date в 16:00? И почему последний new_tally 0.91719 вместо 0.575525 - если они должны добавить до 7? –

ответ

1

Я не уверен, как счастливый 8i будет с этим, но вы можете разделить записи вверх в час (или частичный час) ломти с иерархическим запросом, как это:

select firstoccurrence, lastoccurrence, tally, 
    greatest(firstoccurrence, 
    trunc(firstoccurrence, 'HH24') + (level - 1)/24) as new_start, 
    least(lastoccurrence, 
    trunc(firstoccurrence, 'HH24') + level/24) as new_end 
from t42 
connect by firstoccurrence = prior firstoccurrence 
and prior sys_guid() is not null 
and trunc(firstoccurrence, 'HH24') + (level - 1)/24 
    <= trunc(lastoccurrence, 'HH24'); 

... где t42 - таблица, заполненная как в вашем первом изображении. Это дает:

FIRSTOCCURRENCE  LASTOCCURRENCE  TALLY NEW_START   NEW_END   
------------------- ------------------- ----- ------------------- ------------------- 
2014-12-04 11:33:16 2014-12-04 11:33:36  1 2014-12-04 11:33:16 2014-12-04 11:33:36 
2014-12-30 11:41:46 2014-12-30 16:23:08  7 2014-12-30 11:41:46 2014-12-30 12:00:00 
2014-12-30 11:41:46 2014-12-30 16:23:08  7 2014-12-30 12:00:00 2014-12-30 13:00:00 
2014-12-30 11:41:46 2014-12-30 16:23:08  7 2014-12-30 13:00:00 2014-12-30 14:00:00 
2014-12-30 11:41:46 2014-12-30 16:23:08  7 2014-12-30 14:00:00 2014-12-30 15:00:00 
2014-12-30 11:41:46 2014-12-30 16:23:08  7 2014-12-30 15:00:00 2014-12-30 16:00:00 
2014-12-30 11:41:46 2014-12-30 16:23:08  7 2014-12-30 16:00:00 2014-12-30 16:23:08 

Вы можете использовать его в качестве КТР, или как я не думаю, что 8i знает о КТР вложенное, и вычислить разницу между каждый раз, и это доля от первоначального диапазона, и разделите счет таким образом:

select firstoccurrence, lastoccurrence, tally, new_start, new_end, 
    to_number(to_char(new_start, 'HH24')) as new_hour, 
    tally/((lastoccurrence - firstoccurrence)/(new_end - new_start)) as new_tally 
from (
    select firstoccurrence, lastoccurrence, tally, 
    greatest(firstoccurrence, 
     trunc(firstoccurrence, 'HH24') + (level - 1)/24) as new_start, 
    least(lastoccurrence, 
     trunc(firstoccurrence, 'HH24') + level/24) as new_end 
    from t42 
    connect by firstoccurrence = prior firstoccurrence 
    and prior sys_guid() is not null 
    and trunc(firstoccurrence, 'HH24') + (level - 1)/24 
    <= trunc(lastoccurrence, 'HH24') 
); 

FIRSTOCCURRENCE  LASTOCCURRENCE  TALLY NEW_START   NEW_END    NEW_HOUR NEW_TALLY 
------------------- ------------------- ----- ------------------- ------------------- -------- ----------- 
2014-12-04 11:33:16 2014-12-04 11:33:36  1 2014-12-04 11:33:16 2014-12-04 11:33:36  11 1.000000 
2014-12-30 11:41:46 2014-12-30 16:23:08  7 2014-12-30 11:41:46 2014-12-30 12:00:00  11  .453619 
2014-12-30 11:41:46 2014-12-30 16:23:08  7 2014-12-30 12:00:00 2014-12-30 13:00:00  12 1.492714 
2014-12-30 11:41:46 2014-12-30 16:23:08  7 2014-12-30 13:00:00 2014-12-30 14:00:00  13 1.492714 
2014-12-30 11:41:46 2014-12-30 16:23:08  7 2014-12-30 14:00:00 2014-12-30 15:00:00  14 1.492714 
2014-12-30 11:41:46 2014-12-30 16:23:08  7 2014-12-30 15:00:00 2014-12-30 16:00:00  15 1.492714 
2014-12-30 11:41:46 2014-12-30 16:23:08  7 2014-12-30 16:00:00 2014-12-30 16:23:08  16  .575524 

SQL Fiddle demo; но это 11gR2, поэтому не означает, что он будет работать в 8i. К сожалению, у меня нет такой древней версии.

Если в таблице есть столбец идентификатора, то используйте это для предложения connect by prior. Мне пришлось использовать firstoccurrence и надеяться, что он уникален. Возможно, вам также понадобится использовать dbms_random.value вместо sys_guid() - однако не детерминированная функция будет работать.

+0

Спасибо Alex, im gona попробуйте. – Negashion

Смежные вопросы