创建SQL查询

时间:2011-11-14 10:17:23

标签: sql sql-server sql-server-2008

我有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。

提前谢谢

5 个答案:

答案 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