Separar intervalo de datas por dia

Dúvidas, dicas e truques de SQL, Select, Update, Delete, cláusulas, operações com joins, Funções em SQLs, etc
fernandomartini1984
Rank: Estagiário Sênior
Rank: Estagiário Sênior
Mensagens: 8
Registrado em: Sex, 04 Out 2013 9:41 am

Boa tarde Pessoal,

Tenho o seguinte exemplo:

Selecionar tudo

NR_SEQ_UNIDADE    DT_HISTORICO        DT_FIM_HISTORICO     IE_STATUS_UNIDADE
----------------  -----------------   -----------------    ------------------
140               01/09/2010 16:54    03/09/2010 19:05     A
140               05/09/2010 16:20    07/09/2010 22:15     L
142               01/09/2010 19:07    03/09/2010 20:44     R
142               18/08/2010 18:28    19/08/2010 20:25     L
Preciso criar de uma consulta que separe estes intervalor por dia de maneira que o resultado seja:

Selecionar tudo

NR_SEQ_UNIDADE     DT_HISTORICO        DT_FIM_HISTORICO    IE_STATUS_UNIDADE
---------------    ------------------  ------------------  ------------------
140                01/09/2010 16:54    01/09/2010 23:59    A
140                02/09/2010 00:00    02/09/2010 23:59    A
140                03/09/2010 00:00    03/09/2010 19:05    A
140                05/09/2010 16:20    05/09/2010 23:59    L
140                06/09/2010 00:00    06/09/2010 23:59    L
140                07/09/2010 00:00    07/09/2010 22:15    L
142                01/09/2010 19:07    01/09/2010 23:59    R
142                02/09/2010 00:00    02/09/2010 23:59    R
142                03/09/2010 00:00    03/09/2010 20:44    R
142                18/09/2010 18:28    18/09/2010 23:59    L
142                19/09/2010 00:00    19/09/2010 20:25    L
Não consegui editar de modo que fique facil a visualização. Imagem Anexa...


Poderia me ajudar com este problema?
Muito Obrigado!
Anexos
img.jpg
Avatar do usuário
stcoutinho
Moderador
Moderador
Mensagens: 850
Registrado em: Qua, 11 Mai 2011 5:15 pm
Localização: são Paulo - SP

Olá fernandomartini1984

Você pode ordenar os resultados (ORDER BY): NR_SEQ_UNIDADE ASC, DT_HISTORICO ASC

A sintaxe geral seria: SELECT <colunas> FROM <tabelas> WHERE <condicoes> ORDER BY <colunas>

Abraços ,

Sergio
FernandesRE
Rank: Estagiário Sênior
Rank: Estagiário Sênior
Mensagens: 11
Registrado em: Qui, 08 Jan 2015 9:22 pm

Fernando,

Uma outra alternativa seria você criar uma tabela com todos os dias do ano, ou até adicionar vários anos para mais e para menos, e usá-la no Join.

Eu pensei em uma tabela que tenha a data do dia (sem horas) e outras duas colunas, uma com a hora zero 00:00:00 e a outra com a hora 23:59:59 para simplificar o select, mas daria para usar só uma coluna.

Depois com a ajuda do greatest e do least você consegue ajustar o início e o fim dos dias das extremidades.

Estou formatando meu micro e ainda estou sem o Oracle, mas acho que o select seria algo assim:

Selecionar tudo

select greatest(td.dia_zero_hora, ts.DT_HISTORICO)     dt_inic, 
       least   (td.dia_hora_fim , ts.DT_FIM_HISTORICO) dt_fim
from tab_todos_os_dias td, 
     tab_sua ts
where td.dia between trunc(ts.DT_HISTORICO) and trunc(ts.DT_FIM_HISTORICO)
DanielNN
Moderador
Moderador
Mensagens: 641
Registrado em: Seg, 03 Set 2007 3:26 pm
Localização: Fortaleza - CE
att,

Daniel N.N.

Fernando,

apesar de atrasado venho com uma consulta que traz o resultado desejado.
Com a ajuda do CONNECT BY para conseguir montar os dias dentro de cada intervalo e alguns ajustes, cheguei no resultado:

Selecionar tudo

WITH tabela as (
select 140 UNID , TO_DATE('01/09/2010 16:54','DD/MM/RRRR HH24:MI') DT_INI, TO_DATE('03/09/2010 19:05','DD/MM/RRRR HH24:MI') DT_FIM, 'A' STATUS FROM DUAL
UNION ALL
select 140 UNID , TO_DATE('05/09/2010 16:20','DD/MM/RRRR HH24:MI') DT_INI, TO_DATE('07/09/2010 22:15','DD/MM/RRRR HH24:MI') DT_FIM, 'L' STATUS FROM DUAL
UNION ALL
select 142 UNID , TO_DATE('01/09/2010 19:07','DD/MM/RRRR HH24:MI') DT_INI, TO_DATE('03/09/2010 20:44','DD/MM/RRRR HH24:MI') DT_FIM, 'R' STATUS FROM DUAL
UNION ALL
select 142 UNID , TO_DATE('18/09/2010 18:28','DD/MM/RRRR HH24:MI') DT_INI, TO_DATE('19/09/2010 20:25','DD/MM/RRRR HH24:MI') DT_FIM, 'L' STATUS FROM DUAL
)
,
results as (
    SELECT DISTINCT 
           UNID
           /* SE A DATA DO INTERVALO E A DATA INICIAL FOREM IGUAIS
            , MOSTRA A DATA INICIAL DA TABELA, SENAO MOSTRA A DATA 
              DO INTERVALO ÀS 00:00 , OU SEJA TRUNCADA */ 
         , CASE WHEN TRUNC(DT_INI + LEVEL - 1) <> TRUNC(DT_INI) THEN
                TRUNC(DT_INI + LEVEL - 1)
           ELSE
                DT_INI
           END DATA_INICIAL
           /* SE A DATA DO INTERVALO E A DATA FINAL FOREM IGUAIS
            , MOSTRA A DATA FINAL DA TABELA, SENAO MOSTRA A DATA  
              DO INTERVALO ÀS 23:59 */
         , CASE WHEN TRUNC(DT_INI + LEVEL - 1) <> TRUNC(DT_FIM) THEN
                TRUNC(DT_INI + LEVEL) - 0.00001
           ELSE DT_FIM
           END DATA_FIM         
         , STATUS
      FROM tabela
    CONNECT BY LEVEL <=  (DT_FIM - DT_INI) + 1
    )
    
select *
  from results
order by UNID, DATA_INICIAL
Responder
  • Informação
  • Quem está online

    Usuários navegando neste fórum: Nenhum usuário registrado e 21 visitantes