2015-04-27 35 views
1

一个表的样子:如何在MS SQL Server中减去两个连续的行?

id | location | datetime 
------| ---------| -------- 
CD123 | loc001 | 2010-10-21 13:30:15 
ZY123 | loc001 | 2010-10-21 13:40:15 
YU333 | loc001 | 2010-10-21 13:41:00 
AB456 | loc002 | 2011-1-21 14:30:30 
FG121 | loc002 | 2011-1-21 14:31:00 
BN010 | loc002 | 2011-1-21 14:32:00 

假设表已经按升序排序的日期时间。我正在尝试查找位于之间的两个连续行之间的时间间隔(以秒为单位)。

结果表应该是:

| location | elapse 
| loc001 | 600 
| loc001 | 45 
| loc002 | 30 
| loc002 | 60 

由于id是随机产生的,它是很难写出像a.id = b.id + 1在查询中。只有相同位置的行被连续减去,而不是跨越不同的位置。

我应该如何在MS SQL Server中编写查询来完成它?

+1

添加一个 “新ID” 与日期时间排序的ROW_NUMBER。你可以做你想要的“a.id = b.id + 1” – mxix

回答

2

在SQL Server 2012及更高版本,您可以使用LEADLAG

SELECT 
    location, 
    SUM(DATEDIFF(SECOND, DateTime, 
       Lead(DateTime, 1) OVER(PARTITION BY location ORDER BY DateTime))) Elepase 
FROM 
    tableName 
GROUP BY 
    location 
+0

当你做一个'OVER(分区由位置ORDER BY日期时间)'时,你不能做一个'GROUP BY位置''更不用提'GROUP BY '只会让你每行一行,这不是OP所要求的。 – ughai

+0

感谢您对“LEAD”和“LAG”功能的指导。我发现一个关于这两个函数的教程(http://www.databasejournal.com/features/mssql/lead-and-lag-functions-in-sql-server-2012.html)非常有用。 – Zelong

+0

我在答案中得到了没有'sum'和'group by'的所需结果。正如@ughai所说,我不明白使用'sum'和'group by'。你介意给一个简短的解释吗?谢谢。 – Zelong

0

你有两个选择:

添加新Row number column,然后自加入本上的ID例如[NEW ID] = [NEW ID] - 1.然后可以执行减法操作,即Table1。[New ID] - Table2。[New ID]

使用LAG function这是上述方法的快捷方式。只要您使用SQL2012 +

2
with Result as 
(Select *, ROW_NUMBER() Over (order by location,datetime) RowID from table_name ) 
Select R1.location,DATEDIFF(SECOND,R2.datetime,R1.datetime) from Result R1  Inner join Result R2 on (R1.RowID=R2.RowID+1 and R1.location=r2.location) 
0

创建cte和使用lead在同一行获得datetime和next_datetime。 然后使用该CTE

WITH cte 
    AS 
    (
     SELECT location 
     ,  datetime 
     ,  lead(datetime,1) OVER (patition BY location ORDER BY datetime asc) next_datetime 
     from tbl) 
    SELECT location 
    ,  datediff(ss,next_datetime,datetime) Elepase 
    FROM cte 
+1

介意[解释你的解决方案](http://stackoverflow.com/help/how-to-answer)有点? –

+1

避免代码只有答案。提供一些关于它如何工作的描述。你应该根据'Location'而不是'datetime'进行分区。 – ughai

0

datediff计算你可以试试这个方法:

select s.location, 
     s.datetime, 
     datediff(ss, s.datetime, s.prev_datetime) 
    from (
      select location, 
        datetime, 
        lead(datetime) over (partition by location order by datetime) prev_datetime 
      from Table1 
     ) s 
    where s.prev_datetime is not null 
order by s.location, 
     s.datetime desc