繁体   English   中英

Select 只记录另一个表的时间戳

[英]Select only record until timestamp from another table

我有三张桌子。

第一个是Device

+----------+------+
| DeviceId | Type |
+----------+------+
| 1        | 10   |
| 2        | 20   |
| 3        | 30   |
+----------+------+

第二个是History表——不同设备接收到的数据。

    +----------+-------------+--------------------+
    | DeviceId | Temperature | TimeStamp          |
    +----------+-------------+--------------------+
    | 1        | 31          | 15.08.2020 1:42:00 |
    | 2        | 100         | 15.08.2020 1:42:01 |
    | 2        | 40          | 15.08.2020 1:43:00 |
    | 1        | 32          | 15.08.2020 1:44:00 |
    | 1        | 34          | 15.08.2020 1:45:00 |
    | 3        | 20          | 15.08.2020 1:46:00 |
    | 2        | 45          | 15.08.2020 1:47:00 |
    +----------+-------------+--------------------+

第三个是DeviceStatusHistory

    +----------+---------+--------------------+
    | DeviceId | State  | TimeStamp          |
    +----------+---------+--------------------+
    | 1        | 1(OK)   | 15.08.2020 1:42:00 |
    | 2        | 1(OK)   | 15.08.2020 1:43:00 |
    | 1        | 1(OK)   | 15.08.2020 1:44:00 |
    | 1        | 0(FAIL) | 15.08.2020 1:44:30 |
    | 1        | 0(FAIL) | 15.08.2020 1:46:00 |
    | 2        | 0(FAIL) | 15.08.2020 1:46:10 |
    +----------+---------+--------------------+

我想要 select 设备的最后温度,但只考虑在第一次设备故障之前发生的那些历史记录。

由于device1从 15.08.2020 1:44:30 开始出现故障,我不希望它的记录在该时间戳之后为 go。

device2 也一样

因此,作为最终结果,我只想拥有所有设备的数据,直到它们获得第一个 FAIL 状态:

+----------+-------------+--------------------+
| DeviceId | Temperature | TimeStamp          |
+----------+-------------+--------------------+
| 2        | 40          | 15.08.2020 1:43:00 |
| 1        | 32          | 15.08.2020 1:44:00 |
| 3        | 20          | 15.08.2020 1:46:00 |
+----------+-------------+--------------------+

只有当设备至少失败一次时,我才能 select 获得适当的历史记录:

SELECT * FROM Device D
CROSS APPLY
(SELECT TOP 1 * FROM History H 
WHERE D.Id = H.DeviceId
and H.DeviceTimeStamp < 
(select MIN(UpdatedOn) from DeviceStatusHistory Y where [State]=0 and DeviceId=D.Id)
ORDER BY H.DeviceTimeStamp desc) X
ORDER BY D.Id;

问题是,如果一个设备永远不会出故障,我根本就不知道它的历史。

更新:我的想法是使用这样的东西

SELECT * FROM DeviceHardwarePart HP
CROSS APPLY
(SELECT TOP 1 * FROM History H 
WHERE HP.Id = H.DeviceId
and H.DeviceTimeStamp < 
(select ISNULL((select MIN(UpdatedOn) from DeviceMetadataPart where [State]=0 and DeviceId=HP.Id), 
cast('12/31/9999 23:59:59.997' as datetime)))
ORDER BY H.DeviceTimeStamp desc) X
ORDER BY HP.Id;

我不确定这是否是一个好的解决方案

您可以使用COALESCEcoalesce(min(UpdateOn), cast('9999-12-31 23:59:59' as datetime)) 这确保您始终有 select 而不是NULL的上限。

我会将其视为两部分问题

  1. 我将尝试找出设备发生故障的时间,如果它没有发生故障,我会将其保留为一个较大的值,例如 2099 年的某个时间戳

  2. 一旦我有了上面的内容,我就可以简单地加入历史表并获取失败时间戳之前的最新值。

为了得到一个,我想可以有几种方法。 从我的想法来看,像下面这样的东西应该有效

select device_id, coalesce(min(failed_timestamps), cast('01-01-2099 01:01:01' as timestamp)) as failed_at
(select device_id, case when state = 0 then timestamp else null end as failed_timestamps from History) as X
group by device_id

这为我们提供了特定设备的最小失败时间戳,以及从未失败的设备的任意大值。

我想在此之后解决方案很简单。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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