SQL获取值高于另一个值并保持在另一个值之上的第一个日期/时间

时间:2017-10-31 14:59:32

标签: sql-server

我的表包含值和设定值。我想在违反的设定点期间运行存储过程以获取值被破坏的第一个日期/时间。 SP我显然只是在查询中指定的时间内第一次恢复它,但我希望它适用于当前的漏洞。

实际上我想取消DateAndTime参数,因为违规可能会持续多天。

SELECT TOP (1) DateAndTime
FROM Temps INNER JOIN Temps_Setpoints ON Temps.ProbeID = Temps_Setpoints.ProbeID
WHERE (Temps.ProbeID = @ProbeID) AND (Temps.Temp >= Temps_Setpoints.Hi)
AND DateAndTime BETWEEN '10/31/2017 00:00:00' AND '10/31/2017 23:59:59'
ORDER BY DateAndTime

Hopefully my image will explain better. enter image description here

我认为它在SP中是不可能的,并且可能必须在代码中带回一组日期和循环。

有什么建议吗?

Picture to explain further

2 个答案:

答案 0 :(得分:1)

没有我可以在自己的机器上使用的样本数据(我不需要打字练习),这是未经测试的:

;With CTE as (
SELECT
   DateAndTime,
   Temps.Temp,
   Temp_Setpoints.Hi
FROM Temps INNER JOIN Temps_Setpoints ON Temps.ProbeID = Temps_Setpoints.ProbeID
WHERE (Temps.ProbeID = @ProbeID)
)
SELECT MIN(DateAndTime) as DateAndTime
FROM CTE
WHERE DateAndTime > (select MAX(DateAndTime) from CTE where Temp < Hi)

我已将其作为CTE完成,以便您可以添加更多列,扩展逻辑等。

基本上,我否定了你的前提 - 而不是试图找到“变为真实并保持真实”,我试图找到谓词最后一次 false ,然后选择最早的行之后来了。

(我也使用聚合而不是TOP 1ORDER BY,因为我认为它更清楚地表达了查询的 intent

答案 1 :(得分:0)

我会尝试这样的事情:

SELECT TOP (1) t.DateAndTime
FROM Temps t
INNER JOIN Temps_Setpoints ts
    ON t.ProbeID = ts.ProbeID
WHERE (t.ProbeID = @ProbeID) AND (t.Temp >= ts.Hi)
    AND t.DateAndTime >= '10/31/2017 00:00:00' 
    AND t.DateAndTime <  '11/01/2017 00:00:00'
    AND NOT EXISTS (
        SELECT 1
        FROM Temps ex
        WHERE ex.ProbeID = t.ProbeID
            AND ex.DateAndTime > t.DateAndTime
            AND ex.DateAndTime <  '11/01/2017 00:00:00'
            AND ex.Temp < ts.Hi
    )
ORDER BY t.DateAndTime

我添加了表别名并对所有列进行了限定,以便更清楚地了解哪些表被引用。

NOT EXISTS子查询查找来自同一探头的读数,这些读数之后(但在范围结束之前)记录的温度低于设定值的高度。

我还删除了BETWEEN表达式,因为您可能有小数秒(例如,10/31/2017 23:59:59.253是有效的datetime)。 MyDateTime >= '10/31/2017 00:00' AND MyDateTime < '11/01/2017 00:00:00'通常是一种更好的模式,即使BETWEEN看起来更方便。