目前我的SQL查询是:
select
t.ZoneNumber, t.Mode, t.DeviceA, t.DeviceB, t.LevelA, t.LevelB,
t.Counter, t.Options, t.AzureDeviceID_Field_Device, t.AzureDeviceID,
t.TimeStamp,
tt.ZoneName, tt.AzureDeviceID_Field_Device, tt.ZoneNumber, tt.TimeStamp
from
[dbo].[tblZone] t, [dbo].[tblZoneName] tt
inner join
(select
ZoneNumber, max(TimeStamp) as MaxDate
from
[dbo].[tblZone]
where
AzureDeviceID_Field_Device like 'myFirstDevicea'
group by
ZoneNumber) tm on t.ZoneNumber = tm.ZoneNumber and t.TimeStamp = tm.MaxDate
我要做的是基于DeviceID即AzureDeviceID_Field_Device和Zonenumber,同时查询两个或多个表以查找每个表上的最新记录。
对于我的例子,我的DeviceID也是一个KEY是" myFirstDevicea"。它将产生多个区域的记录,每个区域都有一个例如对于每个区域编号,我只想生成最新的区域编号。
tblZone具有区域参数,并且tbl zonename作为区域的名称。此名称可能会不时更改。
所以我的目标是从tablezone生成一个最近的列表,我可以做,然后从表zonename获取最新的名称。
当我运行查询时,我得到各种不能绑定的错误?
有人可以帮我解决这个问题。
tblZone
tableZoneName
select t.ZoneNumber,t.Mode,t.DeviceA,t.DeviceB,t.LevelA,t.LevelB,t.Counter,t.Options,t.AzureDeviceID_Field_Device,t.AzureDeviceID,t.TimeStamp
from [dbo].[tblZone] t
inner join (select ZoneNumber, max(TimeStamp) as MaxDate FROM [dbo].[tblZone] WHERE AzureDeviceID_Field_Device LIKE 'myFirstDevicea' group by ZoneNumber )tm
on t.ZoneNumber = tm.ZoneNumber and t.TimeStamp = tm.MaxDate
select tt.ZoneName,tt.AzureDeviceID_Field_Device,tt.ZoneNumber,tt.TimeStamp
from [dbo].[tblZoneName] tt
inner join (select ZoneNumber, max(TimeStamp) as MaxDate FROM [dbo].[tblZoneName] WHERE AzureDeviceID_Field_Device LIKE 'myFirstDevicea' group by ZoneNumber )tm
on tt.ZoneNumber = tm.ZoneNumber and tt.TimeStamp = tm.MaxDate
答案 0 :(得分:1)
您可以在common table expression中使用派生表格,使用windowed functions标识两个表格中最新的TimeStamp
值来实现此目的:
-- Built test data:
declare @tblZone table(AzureDeviceID_Field_Device nvarchar(100),Zonenumber int, [TimeStamp] datetime2);
declare @tableZoneName table(AzureDeviceID_Field_Device nvarchar(100),ZoneNumber int, ZoneName nvarchar(100), [TimeStamp] datetime2);
insert into @tblZone values ('a1',1 ,getdate()-2),('a1',1 ,getdate()-1),('a1',1 ,getdate()),('a1',15,getdate()-4),('a1',15,getdate()-3),('a1',15,getdate()-2);
insert into @tableZoneName values ('a1',1 ,'Zone A1',getdate()-2),('a1',1 ,'Zone A1',getdate()-1),('a1',1 ,'Zone A1',getdate()),('a1',15,'Zone A15',getdate()-4),('a1',15,'Zone A15',getdate()-3),('a1',15,'Zone A15',getdate()-2);
-- Common Table Expressions (CTE) to add a Row Number to both tables:
with z as
(
select AzureDeviceID_Field_Device
,Zonenumber
,[TimeStamp] -- row_number() returns the order the rows are in, grouped by the PARTITION columns and ordered by the ORDER BY colmns
,row_number() over (partition by AzureDeviceID_Field_Device, ZoneNumber
order by [TimeStamp] desc
) as rn
from @tblZone
),zn as
(
select AzureDeviceID_Field_Device
,Zonenumber
,ZoneName
,[TimeStamp]
,row_number() over (partition by AzureDeviceID_Field_Device, ZoneNumber
order by [TimeStamp] desc
) as rn
from @tableZoneName
)
-- Join the two derived tables together to get your result:
select *
from z
left join zn
on z.AzureDeviceID_Field_Device = zn.AzureDeviceID_Field_Device
and z.ZoneNumber = zn.Zonenumber
and zn.rn = 1 -- Rows with a rn value of one will have the most recent TimeStamp.
where z.rn = 1
order by z.AzureDeviceID_Field_Device
,z.ZoneNumber;
输出:
+----------------------------+------------+-----------------------------+----+----------------------------+------------+----------+-----------------------------+----+
| AzureDeviceID_Field_Device | Zonenumber | TimeStamp | rn | AzureDeviceID_Field_Device | Zonenumber | ZoneName | TimeStamp | rn |
+----------------------------+------------+-----------------------------+----+----------------------------+------------+----------+-----------------------------+----+
| a1 | 1 | 2017-10-23 09:33:43.3066667 | 1 | a1 | 1 | Zone A1 | 2017-10-23 09:33:43.3233333 | 1 |
| a1 | 15 | 2017-10-21 09:33:43.3066667 | 1 | a1 | 15 | Zone A15 | 2017-10-21 09:33:43.3233333 | 1 |
+----------------------------+------------+-----------------------------+----+----------------------------+------------+----------+-----------------------------+----+