[英]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;
我不确定这是否是一个好的解决方案
您可以使用COALESCE
: coalesce(min(UpdateOn), cast('9999-12-31 23:59:59' as datetime))
。 这确保您始终有 select 而不是NULL
的上限。
我会将其视为两部分问题
我将尝试找出设备发生故障的时间,如果它没有发生故障,我会将其保留为一个较大的值,例如 2099 年的某个时间戳
一旦我有了上面的内容,我就可以简单地加入历史表并获取失败时间戳之前的最新值。
为了得到一个,我想可以有几种方法。 从我的想法来看,像下面这样的东西应该有效
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.