简体   繁体   中英

How to get top 1 record of each group order by desc in SQL Server using linq

I need to get top 1 record order by updatedtime (latest) desc. I'm unable to filer top 1 record from my table

select watertowerid, DOValue, PHValue, WaterTemperature, CurrentTime 
from ParkingSlots 
group by watertowerid, PHValue, DOValue, WaterTemperature, CurrentTime

Sample data:

PHValue DOValue WaterTemperature   watertowerid   CurrentTime
---------------------------------------------------------------------------
 3.00     4.00      22.00               1         2016-09-29 02:34:00
 6.00     4.00      33.00               2         2016-11-29 02:34:00
 8.22     6.55      28.22               1         2016-06-25 01:25:00
30.52     5.60      27.00               2         2016-08-29 02:34:00

Desired output:

PHValue  DOValue   WaterTemperature    watertowerid    CurrentTime
---------------------------------------------------------------------------
  3.00     4.00         22.00               1          2016-09-29 02:34:00
  6.00     4.00         33.00               2          2016-11-29 02:34:00

Use WITH TIES

select TOP(1) with ties *
from ParkingSlots 
order by row_number() over(partition by watertowerid order by CurrentTime DESC);

Use Row_number() function and find latest rows based on currenttime column value.

SELECT [PHValue], [DOValue], [WaterTemperature], [watertowerid], [CurrentTime]
    FROM   (SELECT *,
                   Row_number()
                     OVER(
                       partition BY [watertowerid]
                       ORDER BY currenttime DESC) rno
            FROM   ParkingSlots)a
    WHERE  rno = 1 
CREATE TABLE Table2
    (PHValue int, DOValue int, WaterTemperature int, watertowerid int, CurrentTime datetime)
;

INSERT INTO Table2

VALUES
    (3.00, 4.00, 22.00, 1, '2016-09-29 02:34:00'),
    (6.00, 4.00, 33.00, 2, '2016-11-29 02:34:00'),
    (8.22, 6.55, 28.22, 1, '2016-06-25 01:25:00'),
    (30.52, 5.60, 27.00, 2, '2016-08-29 02:34:00')
;


;WITH cte AS
(
   SELECT *,
         ROW_NUMBER() OVER (PARTITION BY watertowerid ORDER BY CurrentTime DESC) AS rn
   FROM Table2
)
SELECT *
FROM cte
WHERE rn = 1

SELECT *
FROM Table2 D
WHERE CurrentTime = (SELECT MAX(CurrentTime) FROM Table2 WHERE watertowerid = D.watertowerid)

In LINQ (this is assuming Entity Framework, other providers will be similar):

var res = from ps in context.ParkingSlots
          group new { ps.watertowerid, ps.PHValue, ps.DOValue, ps.WaterTemperature, ps.CurrentTime } into groups
          from grp in groups
          let top = (from ps in grp
                     orderby ps.updatedtime
                     select ps).FirstOrDefault()
          where top != null
          select top;

should do it. The second from iterates through the groups allowing ordering, and thus FirstOrDefault in each group. The null check shouldn't be needed (would need an empty group) but with EF to Entities you cannot use First on an inner query.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM