Select 每行中日期值之间的每分钟一行

Select a row for each minute between Date Values in each row

我有一个 table,它的记录以 5 分钟为增量,如下所示:

 UDSNSI     TIMESTAMP
 -8134      7/20/2016 4:30:00 AM
 -8125      7/20/2016 4:35:00 AM
 -8098      7/20/2016 4:40:00 AM

我需要 select 从现在到最后 5 小时,从每分钟到下一行中的时间创建一个结果。例如:

UDSNSI     TIMESTAMP

-8134      7/20/2016 4:30:00 AM
-8134      7/20/2016 4:31:00 AM
-8134      7/20/2016 4:32:00 AM
-8134      7/20/2016 4:33:00 AM
-8134      7/20/2016 4:34:00 AM
-8125      7/20/2016 4:35:00 AM
-8125      7/20/2016 4:36:00 AM
-8125      7/20/2016 4:37:00 AM
...

我觉得我可以使用 "CONNECT BY" 但我似乎无法弄清楚如何告诉它每次使用一行中的 TIMESTAMP 作为开始和下一行作为结束。

 select udsnsi, 
        timestamp
 from plan
 where timestamp <sysdate and timestamp >= sysdate - 5/24

 connect by timestamp <=
 (
     select .... timestamp from row X and row X + 1
                 and create a row for every minute value in between
                 using X's udsnsi value
 )

像这样的东西应该有用。注意使用解析函数 lead() 来识别 "next" 时间。如果每个间隔实际上恰好是五分钟,则您不应该需要它(并且您不需要单独的子查询),因为在这种情况下您可以简单地说 level <= 5。此外,我将列名从 timestamp 更改为 timestp - 使用保留的 Oracle 关键字作为列名是自找麻烦。

with
     plan (    udsnsi, timestp ) as (
       select '-8134', to_date('7/20/2016 4:30:00 PM', 'mm/dd/yyyy hh:mi:ss AM') 
                                                                       from dual union all
       select '-8125', to_date('7/20/2016 4:35:00 PM', 'mm/dd/yyyy hh:mi:ss AM') 
                                                                       from dual union all
       select '-8098', to_date('7/20/2016 4:40:00 PM', 'mm/dd/yyyy hh:mi:ss AM') 
                                                                                 from dual
     ),
     prep (   udsnsi, timestp, next_timestp ) as (
       select udsnsi, timestp, lead(timestp) over (order by timestp)
       from   plan
       where  timestp < sysdate and timestp >= sysdate - 5/24
     )
select udsnsi, timestp + (level - 1) / (24 * 60) as timestp
from   prep
connect by prior udsnsi = udsnsi
and        prior sys_guid() is not null
and        level <= (next_timestp - timestp) * (24 * 60)
order by timestp
;

UDSNSI TIMESTP
------ ----------------------
-8134  07/20/2016 04:30:00 PM
-8134  07/20/2016 04:31:00 PM
-8134  07/20/2016 04:32:00 PM
-8134  07/20/2016 04:33:00 PM
-8134  07/20/2016 04:34:00 PM
-8125  07/20/2016 04:35:00 PM
-8125  07/20/2016 04:36:00 PM
-8125  07/20/2016 04:37:00 PM
-8125  07/20/2016 04:38:00 PM
-8125  07/20/2016 04:39:00 PM
-8098  07/20/2016 04:40:00 PM

ADDED:OP 澄清说间隔始终恰好相隔五分钟。所以解决方法就简单多了:

select udsnsi, timestp + (level - 1) / (24 * 60) as timestp
from   prep
connect by prior udsnsi = udsnsi
  and      prior sys_guid() is not null
  and      level <= 5
;

与第一个解决方案的一个区别:在这个(第二个,更简单的)解决方案中,还将为原始 table 中的 "last" 行添加额外的行。目前还不清楚最后一行的要求是什么,是否需要这些额外的行。