简体   繁体   English

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

[英]Select only record until timestamp from another table

I have three tables.我有三张桌子。

The first one is Device table第一个是Device

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

The second one is History table - data received by different devices.第二个是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 |
    +----------+-------------+--------------------+

The third one is DeviceStatusHistory table第三个是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 |
    +----------+---------+--------------------+

I want to select the last temperature of devices, but take into account only those history records that occurs until the first device failure.我想要 select 设备的最后温度,但只考虑在第一次设备故障之前发生的那些历史记录。

Since device1 starts failing from 15.08.2020 1:44:30, I don't want its records that go after that timestamp.由于device1从 15.08.2020 1:44:30 开始出现故障,我不希望它的记录在该时间戳之后为 go。

The same for the device2 . device2 也一样

So as a final result, I want to have only data of all devices until they get first FAIL status:因此,作为最终结果,我只想拥有所有设备的数据,直到它们获得第一个 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 |
+----------+-------------+--------------------+

I can select an appropriate history only if device failed at least once:只有当设备至少失败一次时,我才能 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;

The problems is, if a device never fails, I don't get its history at all.问题是,如果一个设备永远不会出故障,我根本就不知道它的历史。

Update: My idea is to use something like this更新:我的想法是使用这样的东西

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;

I'm not sure whether it is a good solution我不确定这是否是一个好的解决方案

You can use COALESCE : coalesce(min(UpdateOn), cast('9999-12-31 23:59:59' as datetime)) .您可以使用COALESCEcoalesce(min(UpdateOn), cast('9999-12-31 23:59:59' as datetime)) This ensures you always have an upperbound for your select instead of NULL .这确保您始终有 select 而不是NULL的上限。

I will treat this as two parts problem我会将其视为两部分问题

  1. I will try to find the time at which device has failed and if it hasn't failed I will keep it as a large value like some timestamp in 2099我将尝试找出设备发生故障的时间,如果它没有发生故障,我会将其保留为一个较大的值,例如 2099 年的某个时间戳

  2. Once I have the above I can simply join with histories table and take the latest value before the failed timestamp.一旦我有了上面的内容,我就可以简单地加入历史表并获取失败时间戳之前的最新值。

In order to get one, I guess there can be several approaches.为了得到一个,我想可以有几种方法。 From top of my mind something like below should work从我的想法来看,像下面这样的东西应该有效

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

This gives us the minimum of failed timestamp for a particular device, and an arbitrary large value for the devices which have never failed.这为我们提供了特定设备的最小失败时间戳,以及从未失败的设备的任意大值。

I guess after this the solution is straight forward.我想在此之后解决方案很简单。

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

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