计算值大于 x 的时间(以分钟为单位)
Calculate the time in minutes that a value has been greater than x
我希望能够计算温度列超过特定温度的总时间(以分钟为单位)。例如,我想知道温度在 16 度以上的时间是多少分钟。
如果 12:28
的读数是 16
而 12:30
的读数是 17
,我们说的是从 12:28
到 12:30
,值为 17
.
此外,如果第一个或唯一一个读数高于 x (17),则这将是两分钟,因为设备启动后需要 x 分钟(在本例中为 2 分钟)才能获取第一个读数。
- SerialNumber 是读取温度的设备的序列号。
- CombinDateTime 是获取温度读数的时间。
- The Temperature 是温度值。
SerialNumber, CombinDateTime, Temperature
1000649496, 2018-12-05 10:56:52, 16.6
1000649496, 2018-12-05 10:58:52, 17.3
1000649496, 2018-12-05 11:00:52, 16.8
1000649496, 2018-12-05 11:02:52, 16.6
1000649496, 2018-12-05 11:04:52, 16.4
1000649496, 2018-12-05 11:06:52, 16.3
1000649496, 2018-12-05 11:08:52, 16.3
1000649496, 2018-12-05 11:10:52, 16.2
1000649496, 2018-12-05 11:12:52, 16.2
1000649496, 2018-12-05 11:14:52, 16.2
1000649496, 2018-12-05 11:16:52, 16.2
1000649496, 2018-12-05 11:18:52, 16.2
1000649496, 2018-12-05 11:20:52, 16.1
1000649496, 2018-12-05 11:22:52, 16.1
1000649496, 2018-12-05 11:24:52, 16.1
1000649496, 2018-12-05 11:26:52, 16
1000649496, 2018-12-05 11:28:52, 16
1000649496, 2018-12-05 11:30:52, 16
1000649496, 2018-12-05 11:32:52, 16
1000649496, 2018-12-05 11:34:52, 16.1
1000649496, 2018-12-05 11:36:52, 16.1
1000649496, 2018-12-05 11:38:52, 16.1
1000649496, 2018-12-05 11:40:52, 16.1
1000649496, 2018-12-05 11:42:52, 16.1
1000649496, 2018-12-05 11:44:52, 16.1
1000649496, 2018-12-05 11:46:52, 16.1
1000649496, 2018-12-05 11:48:52, 16
1000649496, 2018-12-05 11:50:52, 16
1000649496, 2018-12-05 11:52:52, 16
1000649496, 2018-12-05 11:54:52, 16
1000649496, 2018-12-05 11:56:52, 16
1000649496, 2018-12-05 11:58:52, 16
1000649496, 2018-12-05 12:00:52, 16.1
1000649496, 2018-12-05 12:02:52, 16.1
1000649496, 2018-12-05 12:04:52, 16.1
1000649496, 2018-12-05 12:06:52, 16.1
1000649496, 2018-12-05 12:08:52, 16
1000649496, 2018-12-05 12:10:52, 16
1000649496, 2018-12-05 12:12:52, 16
1000649496, 2018-12-05 12:14:52, 16
1000649496, 2018-12-05 12:16:52, 16
1000649496, 2018-12-05 12:18:52, 16
1000649496, 2018-12-05 12:20:52, 16
1000649496, 2018-12-05 12:22:52, 16
1000649496, 2018-12-05 12:24:52, 16
1000649496, 2018-12-05 12:26:52, 16
1000649496, 2018-12-05 12:28:52, 16
1000649496, 2018-12-05 12:30:52, 16
1000649496, 2018-12-08 08:08:52, 15.1
1000649496, 2018-12-05 12:32:52, 16
1000649496, 2018-12-05 12:34:52, 16
1000649496, 2018-12-05 12:36:52, 16
1000649496, 2018-12-05 12:38:52, 16
到目前为止我的查询非常基础:
SELECT SerialNumber, CombineDateTime, Temperature
FROM RawData
WHERE Temperature > 16
我想到的原则是我 select 数据集和 order by date
并遍历每一行,直到找到超过 16
的值。然后我获取日期,然后遍历记录,直到找到 <= 16
的值,然后获取该日期和时间以及 datediff()
minutes
中的期间。
我知道你不应该遍历 SQL
条记录,所以我正在考虑使用 CTE
,但我不太确定该怎么做。
我的预期结果例如是:
SerialNumber, MinutesOver
1000649496, 1186
TIA
您希望对日期部分的分钟求和,然后按序列号分组
SELECT SUM(DATEPART(minute, [CombinDateTime])) AS total_call_time , [SerialNumber] FROM [dbo].[Table_1] WHERE [Temperature]>16 GROUP BY [SerialNumber];
这看起来像是一个间隙和孤岛问题(连续> 16个温度和<= 16个温度需要分组在一起),一种解决方案如下:
DECLARE @threshold DECIMAL(18, 2) = 16;
WITH cte1 AS (
SELECT *, CASE
-- first row itself is greater than threshold
WHEN Temperature > @threshold AND LAG(Temperature) OVER (PARTITION BY SerialNumber ORDER BY CombinDateTime) IS NULL THEN 1
-- next row is greater than threshold
WHEN Temperature <= @threshold AND LEAD(Temperature) OVER (PARTITION BY SerialNumber ORDER BY CombinDateTime) > @threshold THEN 1
-- prev row is greater than threshold
WHEN Temperature <= @threshold AND LAG(Temperature) OVER (PARTITION BY SerialNumber ORDER BY CombinDateTime) > @threshold THEN 1
END AS chg
FROM @t
), cte2 AS (
SELECT *, SUM(chg) OVER (PARTITION BY SerialNumber ORDER BY CombinDateTime) AS grp
FROM cte1
)
SELECT SerialNumber
, MIN(CombinDateTime) AS StartDateTime
, MAX(CombinDateTime) AS EndDateTime
, DATEDIFF(SECOND, MIN(CombinDateTime), MAX(CombinDateTime)) / 60.0 AS Total
FROM cte2
GROUP BY SerialNumber, grp
HAVING MAX(Temperature) > @threshold
结果:
SerialNumber StartDateTime EndDateTime Total
1000649496 2018-12-05 10:56:52 2018-12-05 11:24:52 28.000000
1000649496 2018-12-05 11:32:52 2018-12-05 11:46:52 14.000000
1000649496 2018-12-05 11:58:52 2018-12-05 12:06:52 8.000000
具有 LAG
和滚动 SUM
window 功能的解决方案:
DECLARE @ThresholdTemperature DECIMAL(3, 1) = 16
;WITH BreakMarker AS
(
-- Determine if the temperature is above or below the threshold
SELECT
M.*,
LimitMarker = CASE WHEN M.Temperature > @ThresholdTemperature THEN 0 ELSE 1 END
FROM
#Measures AS M
),
LaggedChange AS
(
-- Determine at which point in time the temperature moves between the threshold
SELECT
B.*,
TempChange = CASE WHEN B.LimitMarker = LAG(B.LimitMarker, 1, 0) OVER (
PARTITION BY
B.SerialNumber
ORDER BY
B.CombinDateTime ASC) THEN 0 ELSE 1 END
FROM
BreakMarker AS B
),
BreakGroups AS
(
-- Generate a group ID value to calculate MAX and MIN
SELECT
L.*,
BreakGroup = SUM(TempChange) OVER (PARTITION BY L.SerialNumber ORDER BY L.CombinDateTime ASC)
FROM
LaggedChange AS L
)
SELECT
B.SerialNumber,
MinCombinDateTime = MIN(B.CombinDateTime),
MaxCombinDateTime = MAX(B.CombinDateTime),
MinutesOver = DATEDIFF(MINUTE, MIN(B.CombinDateTime), MAX(B.CombinDateTime))
FROM
BreakGroups AS B
GROUP BY
B.SerialNumber,
B.BreakGroup
HAVING
MIN(B.Temperature) > @ThresholdTemperature
结果:
SerialNumber MinCombinDateTime MaxCombinDateTime MinutesOver
1000649496 2018-12-05 10:56:52.000 2018-12-05 11:24:52.000 28
1000649496 2018-12-05 11:34:52.000 2018-12-05 11:46:52.000 12
1000649496 2018-12-05 12:00:52.000 2018-12-05 12:06:52.000 6
您可以在此处查看 CTE 的临时结果,这样更容易理解分步逻辑:
SerialNumber CombinDateTime Temperature LimitMarker TempChange BreakGroup
1000649496 2018-12-05 10:56:52.000 16.6 0 0 0
1000649496 2018-12-05 10:58:52.000 17.3 0 0 0
1000649496 2018-12-05 11:00:52.000 16.8 0 0 0
1000649496 2018-12-05 11:02:52.000 16.6 0 0 0
1000649496 2018-12-05 11:04:52.000 16.4 0 0 0
1000649496 2018-12-05 11:06:52.000 16.3 0 0 0
1000649496 2018-12-05 11:08:52.000 16.3 0 0 0
1000649496 2018-12-05 11:10:52.000 16.2 0 0 0
1000649496 2018-12-05 11:12:52.000 16.2 0 0 0
1000649496 2018-12-05 11:14:52.000 16.2 0 0 0
1000649496 2018-12-05 11:16:52.000 16.2 0 0 0
1000649496 2018-12-05 11:18:52.000 16.2 0 0 0
1000649496 2018-12-05 11:20:52.000 16.1 0 0 0
1000649496 2018-12-05 11:22:52.000 16.1 0 0 0
1000649496 2018-12-05 11:24:52.000 16.1 0 0 0
1000649496 2018-12-05 11:26:52.000 16.0 1 1 1
1000649496 2018-12-05 11:28:52.000 16.0 1 0 1
1000649496 2018-12-05 11:30:52.000 16.0 1 0 1
1000649496 2018-12-05 11:32:52.000 16.0 1 0 1
1000649496 2018-12-05 11:34:52.000 16.1 0 1 2
1000649496 2018-12-05 11:36:52.000 16.1 0 0 2
1000649496 2018-12-05 11:38:52.000 16.1 0 0 2
1000649496 2018-12-05 11:40:52.000 16.1 0 0 2
1000649496 2018-12-05 11:42:52.000 16.1 0 0 2
1000649496 2018-12-05 11:44:52.000 16.1 0 0 2
1000649496 2018-12-05 11:46:52.000 16.1 0 0 2
1000649496 2018-12-05 11:48:52.000 16.0 1 1 3
1000649496 2018-12-05 11:50:52.000 16.0 1 0 3
1000649496 2018-12-05 11:52:52.000 16.0 1 0 3
1000649496 2018-12-05 11:54:52.000 16.0 1 0 3
1000649496 2018-12-05 11:56:52.000 16.0 1 0 3
1000649496 2018-12-05 11:58:52.000 16.0 1 0 3
1000649496 2018-12-05 12:00:52.000 16.1 0 1 4
1000649496 2018-12-05 12:02:52.000 16.1 0 0 4
1000649496 2018-12-05 12:04:52.000 16.1 0 0 4
1000649496 2018-12-05 12:06:52.000 16.1 0 0 4
1000649496 2018-12-05 12:08:52.000 16.0 1 1 5
1000649496 2018-12-05 12:10:52.000 16.0 1 0 5
1000649496 2018-12-05 12:12:52.000 16.0 1 0 5
1000649496 2018-12-05 12:14:52.000 16.0 1 0 5
1000649496 2018-12-05 12:16:52.000 16.0 1 0 5
1000649496 2018-12-05 12:18:52.000 16.0 1 0 5
1000649496 2018-12-05 12:20:52.000 16.0 1 0 5
1000649496 2018-12-05 12:22:52.000 16.0 1 0 5
1000649496 2018-12-05 12:24:52.000 16.0 1 0 5
1000649496 2018-12-05 12:26:52.000 16.0 1 0 5
1000649496 2018-12-05 12:28:52.000 16.0 1 0 5
1000649496 2018-12-05 12:30:52.000 16.0 1 0 5
1000649496 2018-12-05 12:32:52.000 16.0 1 0 5
1000649496 2018-12-05 12:34:52.000 16.0 1 0 5
1000649496 2018-12-05 12:36:52.000 16.0 1 0 5
1000649496 2018-12-05 12:38:52.000 16.0 1 0 5
1000649496 2018-12-08 08:08:52.000 15.1 1 0 5
您需要为每一行分配一个组。该组可以分配为在每行上或之后超过每行的值的数量。这将包括组中的 "closing" 行。
因此组分配为:
SELECT rd.*,
SUM(CASE WHEN Temperature <= 16 THEN 1 ELSE 0 END) OVER (PARTITION BY SerialNumber ORDER BY CombineDateTime DESC) as grp
FROM RawData rd;
然后就可以使用聚合和过滤了。所以,这个returns你想要的时间跨度:
SELECT SerialNumber,
MIN(CombineDateTime), MAX(CombineDateTime)
FROM (SELECT rd.*,
SUM(CASE WHEN Temperature <= 16 THEN 1 ELSE 0 END) OVER (PARTITION BY SerialNumber ORDER BY CombineDateTime DESC) as grp
FROM RawData rd
) rd
WHERE Temperature > 16
GROUP BY SerialNumber, grp;
最后,您可以计算总分钟数:
SELECT SUM(DATEDIFF(minute, min_cdt, max_cdt)
FROM (SELECT SerialNumber,
MIN(CombineDateTime) as min_cdt,
MAX(CombineDateTime) as max_cdt
FROM (SELECT rd.*,
SUM(CASE WHEN Temperature <= 16 THEN 1 ELSE 0 END) OVER (PARTITION BY SerialNumber ORDER BY CombineDateTime DESC) as grp
FROM RawData rd
) rd
WHERE Temperature > 16
GROUP BY SerialNumber, grp
) s;
我希望能够计算温度列超过特定温度的总时间(以分钟为单位)。例如,我想知道温度在 16 度以上的时间是多少分钟。
如果 12:28
的读数是 16
而 12:30
的读数是 17
,我们说的是从 12:28
到 12:30
,值为 17
.
此外,如果第一个或唯一一个读数高于 x (17),则这将是两分钟,因为设备启动后需要 x 分钟(在本例中为 2 分钟)才能获取第一个读数。
- SerialNumber 是读取温度的设备的序列号。
- CombinDateTime 是获取温度读数的时间。
- The Temperature 是温度值。
SerialNumber, CombinDateTime, Temperature
1000649496, 2018-12-05 10:56:52, 16.6
1000649496, 2018-12-05 10:58:52, 17.3
1000649496, 2018-12-05 11:00:52, 16.8
1000649496, 2018-12-05 11:02:52, 16.6
1000649496, 2018-12-05 11:04:52, 16.4
1000649496, 2018-12-05 11:06:52, 16.3
1000649496, 2018-12-05 11:08:52, 16.3
1000649496, 2018-12-05 11:10:52, 16.2
1000649496, 2018-12-05 11:12:52, 16.2
1000649496, 2018-12-05 11:14:52, 16.2
1000649496, 2018-12-05 11:16:52, 16.2
1000649496, 2018-12-05 11:18:52, 16.2
1000649496, 2018-12-05 11:20:52, 16.1
1000649496, 2018-12-05 11:22:52, 16.1
1000649496, 2018-12-05 11:24:52, 16.1
1000649496, 2018-12-05 11:26:52, 16
1000649496, 2018-12-05 11:28:52, 16
1000649496, 2018-12-05 11:30:52, 16
1000649496, 2018-12-05 11:32:52, 16
1000649496, 2018-12-05 11:34:52, 16.1
1000649496, 2018-12-05 11:36:52, 16.1
1000649496, 2018-12-05 11:38:52, 16.1
1000649496, 2018-12-05 11:40:52, 16.1
1000649496, 2018-12-05 11:42:52, 16.1
1000649496, 2018-12-05 11:44:52, 16.1
1000649496, 2018-12-05 11:46:52, 16.1
1000649496, 2018-12-05 11:48:52, 16
1000649496, 2018-12-05 11:50:52, 16
1000649496, 2018-12-05 11:52:52, 16
1000649496, 2018-12-05 11:54:52, 16
1000649496, 2018-12-05 11:56:52, 16
1000649496, 2018-12-05 11:58:52, 16
1000649496, 2018-12-05 12:00:52, 16.1
1000649496, 2018-12-05 12:02:52, 16.1
1000649496, 2018-12-05 12:04:52, 16.1
1000649496, 2018-12-05 12:06:52, 16.1
1000649496, 2018-12-05 12:08:52, 16
1000649496, 2018-12-05 12:10:52, 16
1000649496, 2018-12-05 12:12:52, 16
1000649496, 2018-12-05 12:14:52, 16
1000649496, 2018-12-05 12:16:52, 16
1000649496, 2018-12-05 12:18:52, 16
1000649496, 2018-12-05 12:20:52, 16
1000649496, 2018-12-05 12:22:52, 16
1000649496, 2018-12-05 12:24:52, 16
1000649496, 2018-12-05 12:26:52, 16
1000649496, 2018-12-05 12:28:52, 16
1000649496, 2018-12-05 12:30:52, 16
1000649496, 2018-12-08 08:08:52, 15.1
1000649496, 2018-12-05 12:32:52, 16
1000649496, 2018-12-05 12:34:52, 16
1000649496, 2018-12-05 12:36:52, 16
1000649496, 2018-12-05 12:38:52, 16
到目前为止我的查询非常基础:
SELECT SerialNumber, CombineDateTime, Temperature
FROM RawData
WHERE Temperature > 16
我想到的原则是我 select 数据集和 order by date
并遍历每一行,直到找到超过 16
的值。然后我获取日期,然后遍历记录,直到找到 <= 16
的值,然后获取该日期和时间以及 datediff()
minutes
中的期间。
我知道你不应该遍历 SQL
条记录,所以我正在考虑使用 CTE
,但我不太确定该怎么做。
我的预期结果例如是:
SerialNumber, MinutesOver
1000649496, 1186
TIA
您希望对日期部分的分钟求和,然后按序列号分组
SELECT SUM(DATEPART(minute, [CombinDateTime])) AS total_call_time , [SerialNumber] FROM [dbo].[Table_1] WHERE [Temperature]>16 GROUP BY [SerialNumber];
这看起来像是一个间隙和孤岛问题(连续> 16个温度和<= 16个温度需要分组在一起),一种解决方案如下:
DECLARE @threshold DECIMAL(18, 2) = 16;
WITH cte1 AS (
SELECT *, CASE
-- first row itself is greater than threshold
WHEN Temperature > @threshold AND LAG(Temperature) OVER (PARTITION BY SerialNumber ORDER BY CombinDateTime) IS NULL THEN 1
-- next row is greater than threshold
WHEN Temperature <= @threshold AND LEAD(Temperature) OVER (PARTITION BY SerialNumber ORDER BY CombinDateTime) > @threshold THEN 1
-- prev row is greater than threshold
WHEN Temperature <= @threshold AND LAG(Temperature) OVER (PARTITION BY SerialNumber ORDER BY CombinDateTime) > @threshold THEN 1
END AS chg
FROM @t
), cte2 AS (
SELECT *, SUM(chg) OVER (PARTITION BY SerialNumber ORDER BY CombinDateTime) AS grp
FROM cte1
)
SELECT SerialNumber
, MIN(CombinDateTime) AS StartDateTime
, MAX(CombinDateTime) AS EndDateTime
, DATEDIFF(SECOND, MIN(CombinDateTime), MAX(CombinDateTime)) / 60.0 AS Total
FROM cte2
GROUP BY SerialNumber, grp
HAVING MAX(Temperature) > @threshold
结果:
SerialNumber StartDateTime EndDateTime Total
1000649496 2018-12-05 10:56:52 2018-12-05 11:24:52 28.000000
1000649496 2018-12-05 11:32:52 2018-12-05 11:46:52 14.000000
1000649496 2018-12-05 11:58:52 2018-12-05 12:06:52 8.000000
具有 LAG
和滚动 SUM
window 功能的解决方案:
DECLARE @ThresholdTemperature DECIMAL(3, 1) = 16
;WITH BreakMarker AS
(
-- Determine if the temperature is above or below the threshold
SELECT
M.*,
LimitMarker = CASE WHEN M.Temperature > @ThresholdTemperature THEN 0 ELSE 1 END
FROM
#Measures AS M
),
LaggedChange AS
(
-- Determine at which point in time the temperature moves between the threshold
SELECT
B.*,
TempChange = CASE WHEN B.LimitMarker = LAG(B.LimitMarker, 1, 0) OVER (
PARTITION BY
B.SerialNumber
ORDER BY
B.CombinDateTime ASC) THEN 0 ELSE 1 END
FROM
BreakMarker AS B
),
BreakGroups AS
(
-- Generate a group ID value to calculate MAX and MIN
SELECT
L.*,
BreakGroup = SUM(TempChange) OVER (PARTITION BY L.SerialNumber ORDER BY L.CombinDateTime ASC)
FROM
LaggedChange AS L
)
SELECT
B.SerialNumber,
MinCombinDateTime = MIN(B.CombinDateTime),
MaxCombinDateTime = MAX(B.CombinDateTime),
MinutesOver = DATEDIFF(MINUTE, MIN(B.CombinDateTime), MAX(B.CombinDateTime))
FROM
BreakGroups AS B
GROUP BY
B.SerialNumber,
B.BreakGroup
HAVING
MIN(B.Temperature) > @ThresholdTemperature
结果:
SerialNumber MinCombinDateTime MaxCombinDateTime MinutesOver
1000649496 2018-12-05 10:56:52.000 2018-12-05 11:24:52.000 28
1000649496 2018-12-05 11:34:52.000 2018-12-05 11:46:52.000 12
1000649496 2018-12-05 12:00:52.000 2018-12-05 12:06:52.000 6
您可以在此处查看 CTE 的临时结果,这样更容易理解分步逻辑:
SerialNumber CombinDateTime Temperature LimitMarker TempChange BreakGroup
1000649496 2018-12-05 10:56:52.000 16.6 0 0 0
1000649496 2018-12-05 10:58:52.000 17.3 0 0 0
1000649496 2018-12-05 11:00:52.000 16.8 0 0 0
1000649496 2018-12-05 11:02:52.000 16.6 0 0 0
1000649496 2018-12-05 11:04:52.000 16.4 0 0 0
1000649496 2018-12-05 11:06:52.000 16.3 0 0 0
1000649496 2018-12-05 11:08:52.000 16.3 0 0 0
1000649496 2018-12-05 11:10:52.000 16.2 0 0 0
1000649496 2018-12-05 11:12:52.000 16.2 0 0 0
1000649496 2018-12-05 11:14:52.000 16.2 0 0 0
1000649496 2018-12-05 11:16:52.000 16.2 0 0 0
1000649496 2018-12-05 11:18:52.000 16.2 0 0 0
1000649496 2018-12-05 11:20:52.000 16.1 0 0 0
1000649496 2018-12-05 11:22:52.000 16.1 0 0 0
1000649496 2018-12-05 11:24:52.000 16.1 0 0 0
1000649496 2018-12-05 11:26:52.000 16.0 1 1 1
1000649496 2018-12-05 11:28:52.000 16.0 1 0 1
1000649496 2018-12-05 11:30:52.000 16.0 1 0 1
1000649496 2018-12-05 11:32:52.000 16.0 1 0 1
1000649496 2018-12-05 11:34:52.000 16.1 0 1 2
1000649496 2018-12-05 11:36:52.000 16.1 0 0 2
1000649496 2018-12-05 11:38:52.000 16.1 0 0 2
1000649496 2018-12-05 11:40:52.000 16.1 0 0 2
1000649496 2018-12-05 11:42:52.000 16.1 0 0 2
1000649496 2018-12-05 11:44:52.000 16.1 0 0 2
1000649496 2018-12-05 11:46:52.000 16.1 0 0 2
1000649496 2018-12-05 11:48:52.000 16.0 1 1 3
1000649496 2018-12-05 11:50:52.000 16.0 1 0 3
1000649496 2018-12-05 11:52:52.000 16.0 1 0 3
1000649496 2018-12-05 11:54:52.000 16.0 1 0 3
1000649496 2018-12-05 11:56:52.000 16.0 1 0 3
1000649496 2018-12-05 11:58:52.000 16.0 1 0 3
1000649496 2018-12-05 12:00:52.000 16.1 0 1 4
1000649496 2018-12-05 12:02:52.000 16.1 0 0 4
1000649496 2018-12-05 12:04:52.000 16.1 0 0 4
1000649496 2018-12-05 12:06:52.000 16.1 0 0 4
1000649496 2018-12-05 12:08:52.000 16.0 1 1 5
1000649496 2018-12-05 12:10:52.000 16.0 1 0 5
1000649496 2018-12-05 12:12:52.000 16.0 1 0 5
1000649496 2018-12-05 12:14:52.000 16.0 1 0 5
1000649496 2018-12-05 12:16:52.000 16.0 1 0 5
1000649496 2018-12-05 12:18:52.000 16.0 1 0 5
1000649496 2018-12-05 12:20:52.000 16.0 1 0 5
1000649496 2018-12-05 12:22:52.000 16.0 1 0 5
1000649496 2018-12-05 12:24:52.000 16.0 1 0 5
1000649496 2018-12-05 12:26:52.000 16.0 1 0 5
1000649496 2018-12-05 12:28:52.000 16.0 1 0 5
1000649496 2018-12-05 12:30:52.000 16.0 1 0 5
1000649496 2018-12-05 12:32:52.000 16.0 1 0 5
1000649496 2018-12-05 12:34:52.000 16.0 1 0 5
1000649496 2018-12-05 12:36:52.000 16.0 1 0 5
1000649496 2018-12-05 12:38:52.000 16.0 1 0 5
1000649496 2018-12-08 08:08:52.000 15.1 1 0 5
您需要为每一行分配一个组。该组可以分配为在每行上或之后超过每行的值的数量。这将包括组中的 "closing" 行。
因此组分配为:
SELECT rd.*,
SUM(CASE WHEN Temperature <= 16 THEN 1 ELSE 0 END) OVER (PARTITION BY SerialNumber ORDER BY CombineDateTime DESC) as grp
FROM RawData rd;
然后就可以使用聚合和过滤了。所以,这个returns你想要的时间跨度:
SELECT SerialNumber,
MIN(CombineDateTime), MAX(CombineDateTime)
FROM (SELECT rd.*,
SUM(CASE WHEN Temperature <= 16 THEN 1 ELSE 0 END) OVER (PARTITION BY SerialNumber ORDER BY CombineDateTime DESC) as grp
FROM RawData rd
) rd
WHERE Temperature > 16
GROUP BY SerialNumber, grp;
最后,您可以计算总分钟数:
SELECT SUM(DATEDIFF(minute, min_cdt, max_cdt)
FROM (SELECT SerialNumber,
MIN(CombineDateTime) as min_cdt,
MAX(CombineDateTime) as max_cdt
FROM (SELECT rd.*,
SUM(CASE WHEN Temperature <= 16 THEN 1 ELSE 0 END) OVER (PARTITION BY SerialNumber ORDER BY CombineDateTime DESC) as grp
FROM RawData rd
) rd
WHERE Temperature > 16
GROUP BY SerialNumber, grp
) s;