Reputation: 9892
In an SQL Server 2008 database, I have tables such as:
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
)
Now I want a query that would pull the last registered, still active device (if any), for all device types.
For a single, given device, that'd be easy:
SELECT TOP 1 *
FROM t_Device
WHERE IsActive = 1
AND DeviceTypeID = 42 -- For example
ORDER BY RegTime DESC
However, I need that for all possible valued of DeviceTypeID
.
I thought I could do it with a JOIN
statement, but there's no way I found to limit the number of records pulled by a JOIN
effectively.
I tried the following:
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
But that only returned the last registered devide of any type.
Anybody has a suggestion?
Thanks,
Upvotes: 1
Views: 208
Reputation: 77677
In SQL Server 2008 you can also use ranking to achieve what you want:
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
Upvotes: 0
Reputation: 23228
You want to get a list of Devices along with their associated maximum RegTime.
SELECT DeviceTypeID, max(RegTime) as LatestRegTime
FROM t_Device
WHERE IsActive = 1
GROUP BY DeviceTypeID
Now you can use this as a derived table and join to it (instead of the select top 1 you tried):
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
Upvotes: 5