在SQL Server 2008数据库中,我有以下表格:
CREATE TABLE t_DeviceType
(
ID INTEGER PRIMARY KEY IDENTITY,
Device VARCHAR(32) NOT NULL
)
CREATE TABLE t_Device
(
ID INTEGER PRIMARY KEY IDENTITY,
DeviceTypeID INTEGER NOT NULL,
IPAddress INTEGER NOT NULL,
RegTime DATETIME NOT NULL,
IsActive BIT NOT NULL
)
现在我想要一个查询,它将为所有设备类型提取最后一个已注册但仍处于活动状态的设备(如果有)。
对于单个给定设备,这很容易:
SELECT TOP 1 *
FROM t_Device
WHERE IsActive = 1
AND DeviceTypeID = 42 -- For example
ORDER BY RegTime DESC
但是,对于DeviceTypeID
所有可能的价值,我需要这样做。
我以为我可以使用JOIN
语句来完成它,但是我无法有效地限制JOIN
提取的记录数。
我尝试了以下内容:
SELECT t_DeviceType.ID AS TypeID,
t_DeviceType.Device,
Device.ID AS DeviceID,
Device.IPAddress AS IPAddress
FROM t_DeviceType
JOIN (
SELECT TOP 1 t_Device.ID, DeviceTypeID, IPAddress
FROM t_Device
JOIN t_DeviceType ON DeviceTypeID = t_DeviceType.ID
WHERE IsActive = 1
ORDER BY RegTime DESC
) AS Device ON Device.ConsoleTypeID = t_DeviceType.ID
但这只返回了任何类型的最后一个注册的偏差。
有人有建议吗?
谢谢,
答案 0 :(得分:5)
您希望获取设备列表及其关联的最大RegTime。
SELECT DeviceTypeID, max(RegTime) as LatestRegTime
FROM t_Device
WHERE IsActive = 1
GROUP BY DeviceTypeID
现在你可以将它作为派生表使用并加入它(而不是你试过的select top 1):
SELECT t_DeviceType.ID AS TypeID,
t_DeviceType.Device,
Device.ID AS DeviceID,
Device.IPAddress AS IPAddress
FROM t_DeviceType
JOIN (
SELECT t_Device.ID,
IPAddress,
DeviceTypeID,
max(RegTime) as LatestRegTime
FROM t_Device
WHERE IsActive = 1
GROUP BY t_Device.ID, IPAddress, DeviceTypeID
) AS Device ON Device.DeviceTypeID = t_DeviceType.ID
答案 1 :(得分:0)
在SQL Server 2008中,您还可以使用ranking来实现您的目标:
SELECT
t.ID AS TypeID,
t.Device,
d.ID AS DeviceID,
d.IPAddress
FROM (
SELECT
*,
rnk = RANK() OVER (PARTITION BY DeviceTypeID ORDER BY RegTime DESC)
FROM t_Device
) d
INNER JOIN t_DeviceType t ON d.DeviceTypeID = t.ID
WHERE d.rnk = 1