我使用带有EF Core的SQL Server。由于缺少EF的GROUP BY支持,因此我运行原始sql查询。
所以,我有一个历史记录表
+------------+---------+------------------+
| HardwareId | StateId | Timestamp |
+------------+---------+------------------+
| Dev1 | 1 | 2019-10-11 11:00 |
| Dev2 | 2 | 2019-10-11 11:01 |
| Dev1 | 3 | 2019-10-11 11:09 |
| Dev2 | 1 | 2019-10-11 11:10 |
| Dev2 | 2 | 2019-10-11 11:10 |
| Dev1 | 3 | 2019-10-11 11:11 |
+------------+---------+------------------+
有些设备记录可以具有相同的时间戳。
现在,我想获取每个设备的最后状态:
+------------+---------+------------------+
| HardwareId | StateId | Timestamp |
+-----==-----+---------+------------------+
| Dev2 | 1 | 2019-10-11 11:10 |
| Dev1 | 3 | 2019-10-11 11:11 |
+------------+---------+------------------+
我跑步
SELECT H.TimeStamp, H.HardwareId, H.ErrorCode, SD.Description FROM History H
INNER JOIN
(SELECT HardwareId, MAX(TimeStamp) LastDateTime from History
GROUP BY HardwareId) AS LastStates
ON H.TimeStamp = LastStates.LastDateTime
INNER JOIN StateDescription SD ON H.ErrorCode = SD.Id ORDER BY H.HardwareId
但是它给了我重复的信息(由于给定设备的时间戳重复,一种设备的多个最后状态。我希望选择这些状态中的任何一个)
+------------+---------+------------------+
| HardwareId | StateId | Timestamp |
+------------+---------+------------------+
| Dev2 | 1 | 2019-10-11 11:10 |
| Dev2 | 2 | 2019-10-11 11:10 |
| Dev1 | 3 | 2019-10-11 11:11 |
+------------+---------+------------------+
添加DISTINCT即可解决
SELECT DISTINCT H.TimeStamp, H.HardwareId, H.ErrorCode, SD.Description FROM History H
INNER JOIN
(SELECT HardwareId, MAX(TimeStamp) LastDateTime from History
GROUP BY HardwareId) AS LastStates
ON H.TimeStamp = LastStates.LastDateTime
INNER JOIN StateDescription SD ON H.ErrorCode = SD.Id ORDER BY H.HardwareId
但是如果我想在最终结果中添加记录ID (H.Id),我显然会再次重复。
SELECT DISTINCT H.TimeStamp, H.Id, H.HardwareId, H.ErrorCode, SD.Description FROM History H
INNER JOIN
(SELECT HardwareId, MAX(TimeStamp) LastDateTime from History
GROUP BY HardwareId) AS LastStates
ON H.TimeStamp = LastStates.LastDateTime
INNER JOIN StateDescription SD ON H.ErrorCode = SD.Id ORDER BY H.HardwareId
如何为每个设备获取某种TOP(1)记录?
答案 0 :(得分:0)
我只会使用row_number()
:
select h.*
from (select h.*,
row_number() over (partition by HardwareId order by timestamp desc) as seqnum
from history h
) h
where seqnum = 1;
这将每天为每台设备精确选择一行。如果当天重复,它将返回一个任意值。如果要全部使用,请使用rank()
代替row_number()
。