我有两张桌子
tblStation
StationId | TPTagId
1 | 7
2 | 8
3 | 9
tblValues
DateAndTime | TPTagId | Val
2017-01-01 13:00:00.000 | 7 | 500
2017-01-01 13:15:00.000 | 7 | 700
2017-01-01 13:30:00.000 | 7 | 750
2017-01-01 13:23:00.000 | 8 | 610
2017-01-01 13:24:00.000 | 8 | 630
2017-01-01 13:25:00.000 | 8 | 640
2017-01-01 13:49:00.000 | 9 | 888
2017-01-01 13:49:30.000 | 9 | 890
2017-01-01 13:49:45.000 | 9 | 901
tblStation中的TagId显示其值存储在tblValues中的位置。
我希望找到每个电台按日期降序排序的前两个值之间的差异。
所以在上面的例子中我的结果集是:
结果
StationId | Difference
1 | 50
2 | 10
3 | 11
是否可以在单个查询中执行此操作?
值表上没有主键,所以我认为这意味着我无法进行自我加入?
到目前为止,我有这个,它通过StationId和DateAndTime降序获取所有站点及其值。但我不知道如何区分每组前两名
select s.StationID, v.DateAndTime, v.Val
from dbo.tblValues v
inner join dbo.tblStation s on s.TPTagId = v.TPTagId
group by s.StationId, v.DateAndTime, v.Val
order by s.StationId, v.DateAndTime desc
答案 0 :(得分:3)
可以使用窗口函数完成:
Create table #values ([DateAndTime] datetime, [TPTagId] int, [Val] int)
insert into #values values ('2017-01-01 13:00:00.000', 7, 500)
insert into #values values ('2017-01-01 13:15:00.000', 7, 700)
insert into #values values ('2017-01-01 13:30:00.000', 7, 750)
insert into #values values ('2017-01-01 13:23:00.000', 8, 610)
insert into #values values ('2017-01-01 13:24:00.000', 8, 630)
insert into #values values ('2017-01-01 13:25:00.000', 8, 640)
insert into #values values ('2017-01-01 13:49:00.000', 9, 888)
insert into #values values ('2017-01-01 13:49:30.000', 9, 890)
insert into #values values ('2017-01-01 13:49:45.000', 9, 901)
;with Last_Dates as
(
Select distinct TPTagId
, First_Value([DateAndTime]) OVER (Partition by [TPTagId] order by [DateAndTime] Desc) as [DateAndTime]
, First_Value([Val]) OVER (Partition by [TPTagId] order by [DateAndTime] Desc) as [Val]
from #values
),
Last_but_one_dates as
(
Select distinct v.TPTagId
, First_Value(v.[Val]) OVER (Partition by v.[TPTagId] order by v.[DateAndTime] Desc) as [Val]
from #values v
left join Last_Dates ld on ld.TPTagId = v.TPTagId and ld.[DateAndTime] = v.[DateAndTime]
where ld.TPTagId is null
)
Select ld.[TPTagId] as StationID, abs(ld.[Val] - lb1.[Val]) as [Difference]
from Last_dates ld
inner join Last_but_one_dates lb1 on ld.[TPTagId] = lb1.[TPTagId]