2015-10-30 164 views
2

我在SQL一组数据,看起来像如下:计算时间

╔═══════════╦═══════╗ 
║ TimeStamp ║ State ║ 
╠═══════════╬═══════╣ 
║ 7:10 AM ║ A ║ 
║ 7:11 AM ║ A ║ 
║ 7:12 AM ║ A ║ 
║ 7:13 AM ║ B ║ 
║ 7:14 AM ║ B ║ 
║ 7:15 AM ║ A ║ 
║ 7:16 AM ║ A ║ 
║ 7:17 AM ║ C ║ 
║ 7:18 AM ║ C ║ 
╚═══════════╩═══════╝ 

我试图计算每个状态的持续时间。但是,我想要分离每个状态序列并分别计算它们的差异,分离重复的状态。所以我想上述数据返回如下所示:

╔═══════╦════════════════════╗ 
║ State ║ Duration (minutes) ║ 
╠═══════╬════════════════════╣ 
║ A ║   2   ║ 
║ B ║   1   ║ 
║ A ║   1   ║ 
║ C ║   1   ║ 
╚═══════╩════════════════════╝ 

有人可以帮忙吗?我怎样才能编写一个返回给我这个数据的SQL查询?

谢谢!

+3

SQL的什么 “品牌” 吗?例如甲骨文? MSSQL? (它可以对解决方案选项产生重大影响)另外:是否有日期列? –

+0

除了“州”列以外是否还有其他顺序?正如你所看到的,使用简单的“GROUP BY”在这里不起作用,因为你实际上需要“State”列的子组(因此也是我的问题)。 –

+0

https://www.simple-talk.com/sql/t-sql-programming/the-sql-of-gaps-and-islands-in-sequences/ http://sqlmag.com/sql-server-2012 /求解隙和 - 岛屿增强窗函数 –

回答

0

那么我会假设需要为MS SQL Server。

为了满足期望的结果(其中,C为1持续时间):

select  
    state, MIN(TimeStamp) StartsAt, EndsAt, datediff(minute,MIN(TimeStamp),EndsAt) DurationMinutes 
from (
     select 
       t1.state, t1.TimeStamp 
       , ISNULL(ca.EndsAt, (select max(timestamp) from table1)) EndsAt 
     from table1 t1 
     outer apply (
        select top (1) t2.timestamp as EndsAt 
        from table1 t2 
        where t1.state <> t2.state and t1.TimeStamp < t2.TimeStamp 
        order by t2.TimeStamp 
      ) ca 
    ) as derived 
group by  
    state, EndsAt 

对于数据的样本,人们可以说,C的持续时间是未知的状态还没有发生变化。在这种情况下,这是一个有点简单:

select  
    state, MIN(TimeStamp) StartsAt, EndsAt, datediff(minute,MIN(TimeStamp),EndsAt) DurationMinutes 
from (
     select 
       t1.state, t1.TimeStamp ,ca.EndsAt 
     from table1 t1 
     outer apply (
        select top (1) t2.timestamp as EndsAt 
        from table1 t2 
        where t1.state <> t2.state and t1.TimeStamp < t2.TimeStamp 
        order by t2.TimeStamp 
      ) ca 
    ) as derived 
group by  
    state, EndsAt 

http://sqlfiddle.com/#!6/f0dd7e/9

0

你没有提到你RDBMS所以这里是适用于任何工作DB的答案。如果您需要快速解决方案,请提及您使用的SQL基础,以便您能够使用某些查询所需的特定功能/命令(访问上一个,下一个记录......)。

SELECT MIN(timeStamp),MAX(timeStamp),State 
FROM(
    SELECT TimeStamp,State,(SELECT count(*) FROM t 
         where state<>t1.state 
         and TimeStamp<t1.TimeStamp) as Grp 
         from t as t1 
    ) as t2 
GROUP BY State,Grp 

SQLFiddle demo