SQL Server:查询以获取来自相同列的两个值之间的数据并计算时间差

时间:2017-07-26 07:17:09

标签: sql sql-server sql-server-2008

我要求获得两个值之间的小时数,比如20和25或更高(这将是用户输入值而不是固定的)。下面是包含样本数据的表格。

01-09-2016 08:40 value_ID上的表25中考虑20上的02-09-2016 13:20,我需要考虑两小时之间的小时数这两个范围即12小时40分钟。同样04-09-2016 13:20它达到26.3(高于25),'06-09-2016 16:20'达到19.3(低于20)和数字小时是45小时。我尝试创建一个函数,但它不起作用..

创建表的代码:

CREATE TABLE [dbo].[NumOfHrs](
[ID] [float] NULL,
[Date] [datetime] NULL,
[Value_ID] [float] NULL
) ON [PRIMARY]

用于插入数据的代码:

INSERT INTO [dbo].[NumOfHrs]
       ([ID]
       ,[Date]
       ,[Value_ID])
 VALUES
(112233,'8-31-2016 08:20:00',19.2),
(112233,'9-01-2016 08:30:00',24),
(112233,'9-01-2016 08:40:00',25),
(112233,'9-01-2016 09:20:00',26),
(112233,'9-02-2016 10:20:00',27),
(112233,'9-02-2016 10:20:00',24),
(112233,'9-02-2016 10:20:00',23),
(112233,'9-02-2016 11:20:00',22),
(112233,'9-02-2016 12:20:00',21),
(112233,'9-02-2016 13:20:00',20),
(112233,'9-03-2016 13:20:00',19.8),
(112233,'9-04-2016 13:20:00',21),
(112233,'9-04-2016 14:20:00',24),
(112233,'9-04-2016 16:20:00',24.6),
(112233,'9-04-2016 19:20:00',26.3),
(112233,'9-04-2016 23:20:00',27),
(112233,'9-05-2016 00:20:00',22),
(112233,'9-06-2016 16:20:00',19.3),
(112233,'9-07-2016 00:20:00',22),
(112233,'9-08-2016 00:20:00',21),
(112233,'9-09-2016 00:20:00',23),
(445566,'9-10-2016 00:20:00',24),
(445566,'9-11-2016 00:20:00',25),
(445566,'9-12-2016 00:20:00',26),
(445566,'9-13-2016 00:20:00',24),
(445566,'9-14-2016 00:20:00',23),
(445566,'9-15-2016 00:20:00',24),
(445566,'9-16-2016 00:20:00',21),
(445566,'9-17-2016 00:20:00',20),
(445566,'9-18-2016 00:20:00',18.5),
(445566,'9-19-2016 00:20:00',17)

表的图像: enter image description here

1 个答案:

答案 0 :(得分:2)

好吧,我想不出更简单的事情。这是我尝试解决问题的方法:

;with NumOfHrs_rn as (
    select id, [Date], Value_ID, 
           row_number() over (partition by id order by [date]) AS rn
    from [dbo].[NumOfHrs] 
), NumOfHrs_lag as (
    select t1.id, t1.[date], 
           t2.Value_ID as prev_value, 
           t1.Value_ID as curr_value           
    from NumOfHrs_rn as t1
    -- get previous value (lag)
    join NumOfHrs_rn as t2 on t1.id = t2.id and t1.rn = t2.rn + 1 
), NumOfHrs_flag as (
    select id, [Date], prev_value, curr_value, 
           case 
              when curr_value >= 25 and prev_value < 25 then 'start'
              when curr_value <= 20 and prev_value > 20 then 'stop'
              else 'ignore'
           end as flag
    from NumOfHrs_lag
), NumOfHrs_grp as ( 
    select id, [Date], curr_value, flag,
           row_number() over (partition by id order by [Date]) -
           case flag
              when 'start' then 0
              when 'stop' then 1
           end as grp
    from NumOfHrs_flag
    where flag in ('start', 'stop')
)
select min([Date]) AS 'start', max([Date]) as 'stop'
from NumOfHrs_grp
group by id, grp
order by min([Date])

<强>输出:

start                    stop
------------------------------------------------
2016-09-01 08:40:00.000  2016-09-02 13:20:00.000
2016-09-04 19:20:00.000  2016-09-06 16:20:00.000
2016-09-11 00:20:00.000  2016-09-17 00:20:00.000

您可以操纵上述查询,以获得以小时/分钟/秒格式表示的时差。

Demo here