T-SQL获得连续的行

时间:2019-01-23 19:55:55

标签: sql sql-server sql-server-2012

我正在尝试编写一个查询,该查询将给出具有五个连续的SensorID行的所有LocIDdatetime,即它们之间的差为1小时,电压为> =6。我可以使用LAG并在数分钟内获得差值,但是如何选择连续的行呢?

输入表:

SensorID LocID DateTime Voltage
-------------------------------
    100 200 1/23/2019 13:00 6 
    100 200 1/23/2019 12:00 8
    100 200 1/23/2019 11:00 6
    100 200 1/23/2019 10:00 7
    100 200 1/23/2019 9:00 8
    101 201 1/23/2019 10:00 8
    101 201 1/23/2019 9:00 1
    101 201 1/23/2019 8:00 2
    101 201 1/23/2019 6:00 8
    101 201 1/23/2019 5:00 1
    103 203 1/23/2019 11:00 10
    103 203 1/23/2019 10:00 11
    103 203 1/23/2019 9:00 8
    103 203 1/23/2019 8:00 9
    103 203 1/23/2019 7:00 9

必填输出:

SensorID LocID DateTime Voltage
-------------------------------
    100 200 01/23/19 1 PM 6
    100 200 01/23/19 12 PM  8
    100 200 01/23/19 11 AM  6
    100 200 01/23/19 10 AM  7
    100 200 01/23/19 9 AM 8
    103 203 01/23/19 11 AM  10
    103 203 01/23/19 10 AM  11
    103 203 01/23/19 9 AM 8
    103 203 01/23/19 8 AM 9
    103 203 01/23/19 7 AM 9

use tempdb
go

Create Table #Input
(
    SensorID int
    , LocID int
    , DateTime datetime 
    , Voltage float
)

Insert Into #Input
Select 100,200,'1/23/2019 13:00',6 Union All
Select 100,200,'1/23/2019 12:00',8 Union All
select 100,200,'1/23/2019 11:00',6 Union All
Select 100,200,'1/23/2019 10:00',7 Union All
Select 100,200,'1/23/2019 9:00',8 Union All
Select 101,201,'1/23/2019 10:00',8 Union All
Select 101,201,'1/23/2019 9:00',1 Union All
Select 101,201,'1/23/2019 8:00',2 Union All
Select 101,201,'1/23/2019 6:00',8 Union All
Select 101,201,'1/23/2019 5:00',1 Union All
Select 103,203,'1/23/2019 11:00',10 Union All
Select 103,203,'1/23/2019 10:00',11 Union All
Select 103,203,'1/23/2019 9:00',8 Union All
Select 103,203,'1/23/2019 8:00',9 Union All
Select 103,203,'1/23/2019 7:00',9

Select * from #Input

drop table #Input
go

1 个答案:

答案 0 :(得分:1)

您可以使用OFFSET argument of LAG向后检查4行,使其成为5行窗口(计算当前值)。 EG:<!DOCTYPE html> <html lang="en"> <head> <script src="https://d3js.org/d3.v4.min.js"></script> <script src="https://unpkg.com/topojson-client@3"></script> <title>National Parks in GeoAlbersUSA Projection</title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <style> body { font-family: Arial, Helvetica, sans-serif; } </style> </head> <body> <header> <h1>World Map Visualization of National Parks</h1> </header> <svg width="960" height="500" fill="none" stroke="#000" stroke-linejoin="round" stroke-linecap="round"></svg> <script> var svg = d3.select("svg"); var path = d3.geoPath(); d3.json("https://unpkg.com/us-atlas@1/us/10m.json", function(error, us) { if (error) throw error; svg.append("path") .attr("stroke", "#aaa") .attr("stroke-width", 0.5) .attr("d", path(topojson.mesh(us, us.objects.counties, function(a, b) { return a !== b && (a.id / 1000 | 0) === (b.id / 1000 | 0); }))); svg.append("path") .attr("stroke-width", 0.5) .attr("d", path(topojson.mesh(us, us.objects.states, function(a, b) { return a !== b; }))); svg.append("path") .attr("d", path(topojson.feature(us, us.objects.nation))); }); d3.csv('https://raw.githubusercontent.com/codebrotherone/2days/master/data/locations.csv', function(d){ var projection = d3.geoAlbersUsa(); var circles = svg.selectAll("circle") .data(d) .enter() .append("circle") .attr("cx",function(d) {return parseFloat(projection([d.longitude, d.latitude])); }) .attr("cy",function(d) { return parseFloat(projection([d.longitude, d.latitude])[1]); }) .attr("r", 1) .attr("fill", 'red') }); </script> </body> </html>,其中column是列,offset是返回的行数,默认是条件失败时返回的内容(默认为lag(Column,Offset,Default))。

NULL

这适用于您的样本数据,但是如果有较大的窗口,您将需要对此进行说明。请参阅此添加的示例数据和用于维护较大窗口的方法。

;with cte as(
select 
    * 
    ,LogicCheck = abs(datediff(hour,[DateTime],lag([DateTime],4) over (partition by SensorID order by [DateTime])))
from #Input
)

select *
from #Input
where SensorID in (select SensorID from cte where LogicCheck = 4)