Sql 确定条纹中的条纹和时间
我有一个简单的表,其中包含buildID UUID,而不是int、Repository、日期和结果:Sql 确定条纹中的条纹和时间,sql,sql-server,sql-server-2012,Sql,Sql Server,Sql Server 2012,我有一个简单的表,其中包含buildID UUID,而不是int、Repository、日期和结果: BuildID Repository BuildDateTime Result ------------------------------------------------------ 1234 Repo1 2017-01-02T01:23:56 Fail 2224 Repo1 2017-01-02T01:22
BuildID Repository BuildDateTime Result
------------------------------------------------------
1234 Repo1 2017-01-02T01:23:56 Fail
2224 Repo1 2017-01-02T01:22:56 Fail
3234 Repo1 2017-01-02T01:20:56 Success
4234 Repo2 2017-01-01T01:20:00 Fail
5234 Repo2 2017-01-01T01:19:00 Success
6234 Repo2 2017-01-01T01:18:00 Success
7234 Repo3 2017-01-01T01:17:30 Success
8234 Repo2 2017-01-01T01:17:00 Success
我想确定,对于每个构建,存储库的构建在一行中有多少个连续构建具有相同的结果,以及何时开始连胜。我想把它放到一个视图中,结果如下所示:
BuildID Repository BuildDateTime Result Streak StreakStartDateTime
-------------------------------------------------------------------------------
1234 Repo1 2017-01-02T01:23:56 Fail 2 2017-01-02T01:22:56
2224 Repo1 2017-01-02T01:22:56 Fail 1 2017-01-02T01:22:56
3234 Repo1 2017-01-02T01:20:56 Success 1 2017-01-02T01:20:56
4234 Repo2 2017-01-01T01:20:00 Fail 1 2017-01-01T01:20:00
5234 Repo2 2017-01-01T01:19:00 Success 3 2017-01-01T01:17:00
6234 Repo2 2017-01-01T01:18:00 Success 2 2017-01-01T01:17:00
7234 Repo3 2017-01-01T01:17:30 Success 1 2017-01-01T01:17:30
8234 Repo2 2017-01-01T01:17:00 Success 1 2017-01-01T01:17:00
我一直在使用lag函数进行实验,它帮助我理解前面的X行。问题是,我需要返回以查找结果的行数因行而异。我开始认为这是一条死胡同
非常感谢您的帮助。这可以通过lag完成
看起来势不可挡,但下面是它的工作原理
检查前一行是否与当前行具有相同的结果,并相应地分配一个标志。
使用运行总和将具有相同值的连续结果分类到同一组中。
获取每个组的最小日期时间,并使用行号根据组计算条纹。
这可以通过延迟来完成
看起来势不可挡,但下面是它的工作原理
检查前一行是否与当前行具有相同的结果,并相应地分配一个标志。
使用运行总和将具有相同值的连续结果分类到同一组中。
获取每个组的最小日期时间,并使用行号根据组计算条纹。
这里有另一种方法。本质上,在历史中为每个构建分配一个顺序,并查找历史中最古老的一个,该构建共享相同的状态,并且中间没有任何不同的状态
WITH CTE_Builds AS (
SELECT *
, RN = ROW_NUMBER() OVER (PARTITION BY Repository ORDER BY BuildDateTime)
FROM BuildHistory
)
SELECT a.*
, Streak = ISNULL(a.RN - x.MIN_RN,0) + 1
, StreakStartDateTime = ISNULL(x.MIN_DATE, a.BuildDateTime)
FROM CTE_Builds a
OUTER APPLY (
SELECT MIN_RN = MIN(RN), MIN_DATE = MIN(BuildDateTime)
FROM CTE_Builds b
WHERE b.Repository = a.Repository
AND b.RN < a.RN
AND b.Result = a.Result
AND NOT EXISTS (
SELECT *
FROM CTE_Builds c
WHERE c.Repository = b.Repository
AND c.RN BETWEEN b.RN and a.RN
AND c.Result != b.Result
)
) x
ORDER BY a.Repository, a.BuildDateTime DESC
这里有另一种方法。本质上,在历史中为每个构建分配一个顺序,并查找历史中最古老的一个,该构建共享相同的状态,并且中间没有任何不同的状态
WITH CTE_Builds AS (
SELECT *
, RN = ROW_NUMBER() OVER (PARTITION BY Repository ORDER BY BuildDateTime)
FROM BuildHistory
)
SELECT a.*
, Streak = ISNULL(a.RN - x.MIN_RN,0) + 1
, StreakStartDateTime = ISNULL(x.MIN_DATE, a.BuildDateTime)
FROM CTE_Builds a
OUTER APPLY (
SELECT MIN_RN = MIN(RN), MIN_DATE = MIN(BuildDateTime)
FROM CTE_Builds b
WHERE b.Repository = a.Repository
AND b.RN < a.RN
AND b.Result = a.Result
AND NOT EXISTS (
SELECT *
FROM CTE_Builds c
WHERE c.Repository = b.Repository
AND c.RN BETWEEN b.RN and a.RN
AND c.Result != b.Result
)
) x
ORDER BY a.Repository, a.BuildDateTime DESC
我没能让它工作-它从来没有返回任何14K构建记录的结果。我没能让它工作-它从来没有返回任何14K构建记录的结果。