krishna mohan
krishna mohan

Reputation: 111

How to get top 1 record of each group based on where clause using group by column in SQL Server

I want the top 1 record of each group, group column is imei. If user has multiple devices, it should show the latest record of all devices.

SQL

SELECT TOP 1 
    p.imei, DEVICEID, timestatmp, ph, do, temp 
FROM 
    dbo.pond AS p
INNER JOIN 
    customerdevices AS cd ON p.imei = cd.imei  
INNER JOIN
    users AS u ON cd.CustomerId = u.CustomerId 
WHERE
    u.username = 'bob'  
ORDER BY
   timestatmp DESC

Sample data

imei            DEVICEID    timestatmp            ph     do     temp
-----------------------------------------------------------------------
869668021752476 1027    2020-03-16 04:33:00.617 7.86    5.04    22.52
869668021752476 1027    2020-03-16 04:03:00.957 7.88    4.99    22.59
869668021732924 1025    2020-03-16 03:57:01.130 7.39    5.40    21.85

Expected output:

imei            DEVICEID    timestatmp            ph     do     temp
-----------------------------------------------------------------------
869668021752476 1027    2020-03-16 04:33:00.617 7.86    5.04    22.52
869668021732924 1025    2020-03-16 03:57:01.130 7.39    5.40    21.85

Upvotes: 1

Views: 133

Answers (2)

DhruvJoshi
DhruvJoshi

Reputation: 17126

you can use ROW_NUMBER() function

SELECT 
imei,
DEVICEID,
timestatmp,
ph,
do,
temp FROM
(
SELECT 
p.imei,
DEVICEID,
timestatmp,
ph,
do,
temp,
RN=ROW_NUMBER() OVER( PARTITION BY p.imei ORDER BY timestatmp DESC) 
FROM dbo.pond as p
inner JOIN customerdevices as cd ON p.imei = cd.imei  inner Join users
as u on cd.CustomerId = u.CustomerId where u.username='bob' )
T
Where T.RN=1 order by timestatmp desc

Upvotes: 0

Tim Biegeleisen
Tim Biegeleisen

Reputation: 521249

You may use TOP 1 WITH TIES in conjunction with ROW_NUMBER, to stick with your current approach:

SELECT TOP 1 WITH TIES p.imei, DEVICEID, timestatmp, ph, do, temp
FROM dbo.pond AS p
INNER JOIN customerdevices AS cd
    ON p.imei = cd.imei
INNER JOIN users AS u
    ON cd.CustomerId = u.CustomerId
WHERE u.username = 'bob'
ORDER BY
    ROW_NUMBER() OVER (PARTITION BY p.imei, DEVICEID ORDER BY timestatmp DESC);

This trick works because all records retained would have a row number of value of 1, which would only occur for the latest record, for each imei and DEVICEID group.

Upvotes: 3

Related Questions