按其他列选择最近的行

Yet*_*ser 3 sql-server sql-server-2008-r2 group-by distinct

我想根据几个因素选择 MS SQL Server 2008 R2 数据库中的最新行。我看到很多人想在网上做同样的事情,并且提出了很多不同的解决方案,但大多数似乎过于复杂,我无法让任何东西正常工作或做我想做的事。

我有一个表中的数据,其中特定事物(房间)将具有名称,以及具有相应日期/时间(LogTimeStanp)的最新状态(AnalogValue;它与在线状态相关)。

我最感兴趣的是每个房间的当前在线状态,所以我只需要每个房间的最新行。

  • 可以有多个房间,例如 1 - 5,000(没有强加的上限)。
  • 当我查看历史在线状态时,有很多数据会回溯。
  • 此表中还有其他我对此查询不感兴趣的数据。
  • 我必须加入表格以获得可读的房间名称,否则我只有一个 GUID。
  • 我不知道如果我需要使用MAX()SELECT DISTINCTGroup by,或别的东西。我一直无法让这些工作令我满意。

此代码不起作用,但应该让您了解我想要做什么:

SELECT r.RoomName, a.AttributeID, a.AnalogValue, max(a.LogTimeStamp)
  FROM CRV_AttributeLog a join CRV_Rooms r on a.RoomID=r.RoomID
  where a.AttributeID like 'online_status'
Run Code Online (Sandbox Code Playgroud)

我的目的是获得每个房间的最大(最近)LogTimeStamp 的模拟值。

我得到了一个与 group by 一起运行的查询,但它似乎没有对其进行分组(当然也不是按房间名称),所以我想我做错了。

更新 1、2、3、4

添加了图片作为上下文。此外,此查询将构成报告的基础,因此它必须完全具有参考性,这就是为什么我只想要“最新”的在线状态。更复杂的是,“最新的”可能不会在今天、本周或本月发生。但它就在那里,在某个地方,某个时间。

CRV_AttributeLog 中的每一行都有自己的 AttributeID 和 AnalogValue,并且该行通过时间戳 (LogTimeStamp) 成为唯一的。否则, AttributeID 和 AnalogValue 完全有可能跨行匹配(没关系)。此表记录有关何时更改一些不同内容的信息:在线状态、是否出现错误等。 ONLINE_STATUS可以从 0-2(离线、部分在线、在线)更改,并且会在它们之间定期更改。其他 AttributeID 的模拟值也可能会根据其他条件来回更改。

在此处输入图片说明

在此处输入图片说明

期望输出

Room Name          AttributeID     AnalogValue     LogTimeStamp
Conference Room    ONLINE_STATUS   0               2016-06-11 21:21:25:123
Gymnasium          ONLINE_STATUS   1               2016-07-21 20:23:45:456
Boardroom          ONLINE_STATUS   2               2017-02-17 05:15:37:951
Great Hall         ONLINE_STATUS   0               2016-10-23 07:28:54:753
...
Run Code Online (Sandbox Code Playgroud)

McN*_*ets 5

如果有多个 AnalogValue,您可以获取每个 RoomId 的最大值,然后使用 CRV_AttributeLog JOIN 以获取所有属性。

WITH maxTime as
(
    SELECT   RoomId, MAX(LogTimeStamp) AS LogTimeStamp
    FROM     @CRV_AttributeLog
    WHERE    AttributeID LIKE N'online_status'
    GROUP BY RoomId
)
SELECT  r.RoomName, 
        a.AttributeId, 
        a.AnalogValue,
        m.LogTimeStamp
  FROM  @CRV_AttributeLog a 
  JOIN  maxTime m 
    ON  a.RoomID = m.RoomID
   AND  a.LogTimeStamp = m.LogTimeStamp
   AND  a.AttributeId LIKE N'online_status'
  JOIN  @CRV_Rooms r
    ON  r.RoomId = a.RoomId; 

+-----------------+---------------+-------------+---------------------+
|     RoomName    |  AttributeId  | AnalogValue | LogTimeStamp        |
+-----------------+---------------+-------------+---------------------+
| Great Hall      | online_status |      1      | 01.01.2017 20:21:00 |
| Boardroom       | online_status |      0      | 01.01.2017 21:40:00 |
| Conference room | online_status |      1      | 01.01.2017 20:20:00 |
| Gymnasium       | online_status |      2      | 01.01.2017 18:20:00 |
+-----------------+---------------+-------------+---------------------+
Run Code Online (Sandbox Code Playgroud)

在这里查看:http : //rextester.com/HISDOM70855