我有一个表每秒接收一行,每秒一个活动状态与时间戳一起传递。我需要根据状态的特定变化进行分组,例如当状态从6变为0然后全部跟随0之后再直到状态变化。 解释这个问题的最好方法就是一个例子:
| 13:05:00 | 1 |
| 13:05:05 | 0 |
| 13:05:10 | 0 |
| 13:05:15 | 6 |
| 13:05:20 | 6 |
| 13:05:25 | 0 |
| 13:05:30 | 0 |
| 13:05:35 | 6 |
| 13:05:40 | 6 |
| 13:05:45 | 0 |
| 13:05:50 | 0 |
我希望从这个表中得到的结果是2组,(状态从6到0有2个变化)将所有状态为6的状态分组,直到状态再次变化。 δ13:05:25,13:05:30取代;δ13:05:45,13:05:50为烷基;
答案 0 :(得分:1)
CREATE TABLE MyTable
(
[TimeStamp] NVARCHAR(10),
[State] INT
)
INSERT INTO MyTable ([TimeStamp], [State])
SELECT '13:05:00', 1
UNION ALL
SELECT '13:05:05', 0
UNION ALL
SELECT '13:05:10', 0
UNION ALL
SELECT '13:05:15', 6
UNION ALL
SELECT '13:05:20', 6
UNION ALL
SELECT '13:05:25', 0
UNION ALL
SELECT '13:05:30', 0
UNION ALL
SELECT '13:05:35', 6
UNION ALL
SELECT '13:05:40', 6
UNION ALL
SELECT '13:05:45', 0
UNION ALL
SELECT '13:05:50', 0
GO
;WITH cte( [RowNum], [TimeStamp], [State]) AS
(
SELECT ROW_NUMBER() OVER(ORDER BY TIMESTAMP), TIMESTAMP, STATE FROM MyTable
)
SELECT
t2.TimeStamp AS [Start],
ISNULL
(
(SELECT TimeStamp FROM cte WHERE RowNum = (SELECT TOP 1 RowNum FROM cte WHERE State <> 0 AND RowNum > t2.RowNum ORDER BY TimeStamp)-1)
,(SELECT MAX(TimeStamp) FROM cte)
) [End]
FROM cte t1
JOIN cte t2 ON t1.RowNum = t2.RowNum - 1
WHERE t1.State = 6 AND t2.State = 0
GO
答案 1 :(得分:0)
不确定问题是否足够清楚:|所以我以另一种方式接近它,因为找到从6到0的第一个变化很容易做到:
with x as (
select *, rn = ROW_NUMBER() OVER (ORDER BY Activity_Time)
FROM WellData_Activity
)
Select x.Activity_Code, x.Activity_Time
from x left outer join x as y
on x.rn = y.rn + 1
and x.Activity_Code <> y.Activity_Code
where y.activity_code is not null
但是一系列activity_codes的分组更难以同时完成,所以我用它首先对它们进行分组(按时间顺序按activity_code)然后我可以运行第一个查询来返回一行(现在返回开始/结束):
WITH periods AS (
SELECT
*,
grp = ROW_NUMBER() OVER (PARTITION BY Well_GUID ORDER BY Activity_Time)
- ROW_NUMBER() OVER (PARTITION BY Well_GUID, Activity_Code ORDER BY Activity_Time)
FROM WellData_Activity
)
SELECT
Well_GUID,
date_from = MIN(Activity_Time),
date_to = MAX(Activity_Time),
Activity_Code
FROM periods
GROUP BY
Well_GUID,
Activity_Code,
grp
ORDER BY
Well_GUID,
MIN(Activity_Time)