我有以下数据:
ID SESSION START_DATE END_DATE
1 A 01/01/2016 22:35 02/01/2016 02:35
1 B 02/01/2016 02:35 02/01/2016 04:45
2 A 01/01/2016 00:00 01/01/2016 02:00
2 B 01/01/2016 02:00 01/01/2016 03:30
我需要像这样回来:
ID SESSION START_DATE END_DATE
1 A 01/01/2016 22:35 01/01/2016 22:59
1 A 01/01/2016 23:00 01/01/2016 23:59
1 A 02/01/2016 00:00 02/01/2016 00:59
1 A 02/01/2016 01:00 02/01/2016 01:59
1 A 02/01/2016 02:00 02/01/2016 02:35
1 B 02/01/2016 02:35 02/01/2016 02:59
1 B 02/01/2016 03:00 02/01/2016 03:59
1 B 02/01/2016 04:00 02/01/2016 04:45
2 A 01/01/2016 00:00 01/01/2016 00:59
2 A ...
任何帮助?
答案 0 :(得分:0)
这是一个解决方案,你只需要一点小时提取:
create table connect_by_hour_test(id number, sess varchar2(1), start_date date, end_date date);
insert into connect_by_hour_test (id, sess, start_date, end_date) values (1, 'A', to_date('01/01/2016 22:30', 'dd/mm/yyyy hh24:mi'), to_date('02/01/2016 02:35', 'dd/mm/yyyy hh24:mi'));
insert into connect_by_hour_test (id, sess, start_date, end_date) values (1, 'B', to_date('02/01/2016 02:35', 'dd/mm/yyyy hh24:mi'), to_date('02/01/2016 04:45', 'dd/mm/yyyy hh24:mi'));
insert into connect_by_hour_test (id, sess, start_date, end_date) values (2, 'A', to_date('01/01/2016 00:00', 'dd/mm/yyyy hh24:mi'), to_date('01/01/2016 02:00', 'dd/mm/yyyy hh24:mi'));
insert into connect_by_hour_test (id, sess, start_date, end_date) values (2, 'B', to_date('01/01/2016 02:00', 'dd/mm/yyyy hh24:mi'), to_date('01/01/2016 03:30', 'dd/mm/yyyy hh24:mi'));
commit;
with max_level as (
select id, sess, ceil((end_date - start_date) / (1/24)) as val from connect_by_hour_test ) -- get the max number of iterations for each (id, sess) pair
select distinct
id,
sess,
decode(level, 1, to_char(start_date, 'dd/mm/yyyy hh24:mi'), to_char(trunc(start_date, 'hh24') + 1/24 * level - 1/24, 'dd/mm/yyyy hh24:mi')) start_date, -- if first iteration in pair show the start_date, otherwise show the start date, plus the number of hours for the current iteration(first iteration - 1 hour, 2nd iteration - two hours, etc) minus one minute
decode(level, (select val from max_level ml where ml.id = src.id and ml.sess = src.sess), to_char(end_date, 'dd/mm/yyyy hh24:mi'), to_char(trunc(start_date, 'hh24') + 1/24 * level - 1/24/60, 'dd/mm/yyyy hh24:mi')) end_date -- if last iteration show end_date, otherwise show value from previous iteration plus one minute
from
connect_by_hour_test src
connect by
trunc(start_date, 'hh24') + 1/24 * (level - 1) <= end_date order by 1,2;
编辑:在反馈后进行更正,将步骤添加到级别-1,将max_level计算为ceil,而不是截断,结束时为end_date - start_date
答案 1 :(得分:0)
您可以尝试这样的事情:
SELECT DISTINCT session,
id,
st,
end
FROM ( SELECT DECODE(LEVEL, 1, start_date, TRUNC(start_date, 'HH') + (LEVEL - 1) / 24) st,
PRIOR id p_id,
id,
PRIOR session p_session,
session,
LEAST(end_date, TRUNC(start_date, 'HH') + (LEVEL) / 24 - 1 / 24 / 60) end
FROM tab
CONNECT BY LEVEL <= EXTRACT(HOUR FROM end_date - start_date) + 1)
WHERE ( p_id = id
AND p_session = session)
OR (p_id IS NULL)
我想避免使用DISTINCT,但找不到办法,希望别人可以提供更好的解决方案
答案 2 :(得分:0)
选择级别,
NR_ATENDIMENTO,
CD_SETOR_ATENDIMENTO,
最大的(DT_ENTRADA_UNIDADE,trunc(DT_ENTRADA_UNIDADE +(level-1)/ 24,&#39; hh24&#39;)DT_ENTRADA_UNIDADE,
to_char(trunc(DT_ENTRADA_UNIDADE,&#39; hh24&#39;)+ 1/24 *级别 - 1/24/60,&#39; dd / mm / yyyy hh24:mi:ss&#39;)DT_SAIDA_UNIDADE
从
(
选择
CD_SETOR_ATENDIMENTO,
NR_SEQ_INTERNO,
DT_ENTRADA_UNIDADE,
nvl(DT_SAIDA_UNIDADE,sysdate)DT_SAIDA_UNIDADE,
NR_ATENDIMENTO
来自ATEND_PACIENTE_UNIDADE
OBTER_TIPO_UNIDADE_ATEND(NR_ATENDIMENTO,NR_SEQ_INTERNO,IE_PASSAGEM_SETOR)不在(&#39; S&#39;)
AND nr_atendimento = 831838
由NR_ATENDIMENTO订购,
CD_SETOR_ATENDIMENTO,
DT_ENTRADA_UNIDADE DESC
)
在哪里1 = 1
CONNECT BY ROWID = PRIOR ROWID
和trunc(DT_ENTRADA_UNIDADE,&#39; hh24&#39;)+ 1/24 *(level-1)&lt; = nvl(DT_SAIDA_UNIDADE,sysdate)
AND PRIOR SYS_GUID()不是NULL
按2,3,4排序;