Reputation: 122
I have a table that looks something like this:
+--------+-------+-------+ |TestName|TestRun|OutCome| +--------+-------+-------+ | Test1 | 1 | Fail | +--------+-------+-------+ | Test1 | 2 | Fail | +--------+-------+-------+ | Test2 | 1 | Fail | +--------+-------+-------+ | Test2 | 2 | Pass | +--------+-------+-------+ | Test3 | 1 | Pass | +--------+-------+-------+ | Test3 | 2 | Fail | +--------+-------+-------+
The table is used for storing a brief summary of test results. I want to write a query (using T-SQL but any dialect is fine) that returns how many build each test has been failing. Use the example as input and it should return a result set like this:
+--------+----------+ |TestName|Regression| +--------+----------+ | Test1 | 2 | +--------+----------+ | Test2 | 0 | +--------+----------+ | Test3 | 1 | +--------+----------+
Note that the query should ONLY count current 'fail streak' instead of counting the total number of failures. Can assume MAX(TestRun) is the most recent run.
Any ideas?
Edit: grammar
Upvotes: 0
Views: 631
Reputation: 3922
A bit ugly but it works.
create table dbo.tests
(
TestName nvarchar(10) not null
, TestRun int not null
, OutCome nvarchar(10) not null
)
insert into dbo.tests
select 'Test1', 1, 'Fail'
union all
select 'Test1', 3, 'Fail'
union all
select 'Test2', 1, 'Fail'
union all
select 'Test2', 3, 'Pass'
union all
select 'Test3', 1, 'Pass'
union all
select 'Test3', 3, 'Fail'
; with c (TestName, TestRun, OutCome, TestId)
as
(
select TestName, TestRun, OutCome
, dense_rank() over (order by TestRun) as TestId
from dbo.tests
)
select t.TestName, max(t.TestId) - mt.MaxPassedTestRun as FailedRuns
from c t
inner join
(
select TestName, sum(TestId) as MaxPassedTestRun
from
(
select TestName, TestId
from c
where OutCome = 'Pass'
union all
select TestName, 0 as TestRun
from c
where OutCome = 'Fail'
) mt
group by mt.TestName
) mt on t.TestName = mt.TestName
group by t.TestName, MaxPassedTestRun, mt.MaxPassedTestRun
Upvotes: 3
Reputation: 32455
Here is another approach using CTE:
;WITH streaks AS (
SELECT t.Name, t.Run, t.Outcome
FROM TestRuns t
INNER JOIN (SELECT Name, MAX(Run) AS MaxRun FROM TestRuns GROUP BY Name) maxes
ON maxes.Name = t.Name AND maxes.MaxRun = t.Run
UNION ALL
SELECT t.Name, t.Run, t.Outcome
FROM TestRuns t
INNER JOIN streaks s ON s.Name = t.Name AND s.Outcome = 0
WHERE t.Run = s.Run - 1 AND t.Outcome = 0
)
SELECT Name
, SUM(CASE WHEN Outcome = 0 THEN 1 ELSE 0 END) AS Regression
FROM streaks
GROUP BY Name
Here a SQL Fiddle with sample of data
Upvotes: 1
Reputation: 3466
select a.TestName,a.TestRun,a.Outcome From table1 a join
Table1 b on a.TestName=b.testname
and a.Outcome='Fail'
and a.TestRun>b.TestRun
Upvotes: 1