我有DeviceMaster和DeviceStatus的表。 其中DeviceMaster是设备的主设备,DeviceStatus是设备的状态。现在我想获取每台设备的最新DeviceStatus记录,其中只有一行使用DeviceMasterId并且根据最后一行(降序)
例如
DeviceName RecordCreatedDate Status
ElectronicRod 14/11/2011 12:00:00 On
ElectronicRod 14/11/2011 11:30:00 Off
即使DeviceStatus中有多条记录。
这是表结构
DeviceMaster
[Id] [int],
[ROId] [int] ,
[ClientId] [int] ,
[DeviceTypeId] [int] ,
[Label] [varchar](50) ,
[ClientCommChannelId] [int] ,
[ServerCommChannelId] [bigint] ,
[DeviceName] [varchar](50) ,
[Address] [varchar](50) ,
[Attribute1] [varchar](50) ,
[Attribute2] [varchar](50) ,
[Attribute3] [varchar](50) ,
[IsDeleted] [bit] ,
[RecordCreatedDate] [datetime] ,
[RecordUpdatedDate] [datetime] ,
[RecordCreatedBy] [int] ,
[RecordUpdatedBy] [int] ,
[IsTransfered] [bit]
DeviceStatus
[Id] [bigint],
[ROId] [int],
[ClientId] [int],
[ServerDeviceId] [bigint] , --It is the foreign key reference of Device Id
[ClientDeviceId] [int] ,
[Status] [bit] ,
[TimeStamp] [datetime] ,
[Attribute1] [varchar](50) ,
[Attribute2] [varchar](50) ,
[Attribute3] [varchar](50) ,
[RecordCreatedDate] [datetime] ,
[RecordUpdatedDate] [datetime] ,
[RecordCreatedBy] [int] ,
[RecordUpdatedBy] [int] ,
[IsTransfered] [bit]
DeviceStatus具有单个设备的多行条目。我需要为每个设备提供最新的DeviceStatus。
提前谢谢
答案 0 :(得分:1)
您可以将CTE(公用表表达式)与ROW_NUMBER
函数一起使用:
;WITH LastPerDevice AS
(
SELECT
dm.DeviceName, ds.RecordCreatedDate, ds.Status,
ROW_NUMBER() OVER(PARTITION BY dm.DeviceMasterId
ORDER BY ds.RecordCreatedDate DESC) AS 'RowNum'
FROM dbo.DeviceMaster dm
INNER JOIN dbo.DeviceStatus ds ON ds.DeviceMasterId = dm.DeviceMasterId
)
SELECT
DeviceName, RecordCreatedDate, Status
FROM LastPerDevice
WHERE RowNum = 1
此CTE按DeviceMasterId
对您的数据进行“分区”,对于每个分区,ROW_NUMBER
函数会发出序号,从1开始并按RecordCreatedDate DESC
排序 - 所以最新row获取RowNum = 1
(对于每个DeviceMasterId
),这是我在后面的SELECT语句中从CTE中选择的。
答案 1 :(得分:0)
select dm.DeviceName, ds1.LatestDate, ds2.Status
from DeviceMaster dm,
(select ServerDeviceId, max(RecordCreatedDate) as LatestDate
from DeviceStatus
group by ServerDeviceId) ds1,
DeviceStatus ds2
where dm.Id = ds1.ServerDeviceId
and dm.Id = ds2.ServerDeviceId
and ds1.LatestDate = ds2.RecordCreatedDate
order by ds1.LatestDate desc
答案 2 :(得分:0)
我不是肯定你正在寻找什么,但以下使用where子句中的子查询来过滤最后一个日期。也许如果这不是您正在寻找的东西,它可能会帮助您找到它。如果您需要我澄清任何事情,请告诉我。
select DeviceName, RecordCreateDated, Status
from DeviceMaster dm join
DeviceStatus ds on dm.Id = ds.ServiceDeviceId
where DeviceName = 'ElectronicRod' and
RecordCreateDate =
(select max(RecordCreatedDate)
from DeviceMaster dm1 join
DeviceStatus ds1 on dm1.Id = ds1.ServiceDeviceId
where dm1.DeviceName = dm.DeviceName)
答案 3 :(得分:0)
使用max(),按方法分组
你的代码看起来有点像这样:
SELECT max("DeviceStatus") as "devicestatus" , "Id" FROM "DeviceMaster"
group by "Id";
编辑:
SELECT max("RecordCreatedDate") as "Date" , "DeviceName" FROM "DeviceMaster"
group by "Name";
答案 4 :(得分:0)
您希望从每个设备的状态表中获取最新记录的状态。 这意味着您需要实际对Status表进行两次连接 - 一个表获取最新行(由设备分组),然后再次获取该最新状态的状态。像这样:
我看到你有BIGINTS - 这告诉我Status状态表很大。这表明它经常更新。确保Status表已在ServerDeviceId上编入索引。
select DeviceName ,ds.RecordCreatedDate,ds.Status
from
DeviceMaster dm inner join
(select ServerDeviceId,MAX(Id) DeviceStatusId from DeviceStatus
group by ServerDeviceId) laststatus
on laststatus.ServerDeviceId= dm.Id inner join
DeviceStatus ds
on ds.Id = laststatus.DeviceStatusId