2012-06-19 2 views
2

Это трудно объяснить, но из этого примера должно быть ясно.TSQL - COUNT количество строк в другом состоянии, чем текущая строка

Таблица ТАБЛИЦА:

Name State Time 
-------------------- 
A  1  1/4/2012 
B  0  1/3/2012 
C  0  1/2/2012 
D  1  1/1/2012 

Хотелось бы

select * from TABLE where state=1 order by Time desc 

плюс дополнительный столбец «Пропущенные», содержащий число строк, после того, как тот, где состояние = 1 в состояние 0, другими словами, выход должен выглядеть следующим образом:

Name State Time  Skipped 
A 1  1/4/2012 2  -- 2 rows after A where State != 1 
D 1  1/1/2012 0  -- 0 rows after D where State != 1 

0 также следует сообщать в случае, если 2 последовательных ряда являются в состоянии = 1, т. е. между этими строками нет ничего, кроме 1.

Кажется, что CTE здесь, но не может понять, как подсчитывать строки, где состояние! = 1. Любая помощь будут оценены.

(MS SQL Server 2008)

ответ

0

Хорошо, вот вы идете (он получает немного грязный):

SELECT U.CurrentTime, 
     (SELECT COUNT(*) 
     FROM StateTable AS T3 
     WHERE T3.State=0 
     AND T3.Time BETWEEN U.LastTime AND U.CurrentTime) AS Skipped  
FROM (SELECT T1.Time AS CurrentTime, 
      (SELECT TOP 1 T2.Time 
       FROM StateTable AS T2 
       WHERE T2.Time < T1.Time AND T2.State=1 
       ORDER BY T2.Time DESC) AS LastTime 
     FROM StateTable AS T1 WHERE T1.State = 1) AS U 
2

Я использовал КТР установить Ровно, так что вы не зависит от последовательных дат:

WITH CTE_Rows as 
(
    select name,state,time, 
    rowno = ROW_NUMBER() over (order by [time]) 
    from MyTable 
) 
select name,state,time, 
    gap = isnull(r.rowno - x.rowno - 1,0) 
from 
    CTE_Rows r 
    outer apply (
     select top 1 rowno 
     from CTE_Rows sub 
     where sub.rowno < r.rowno and sub.state = 1 
     order by sub.rowno desc) x 
where r.state = 1 

Если вы просто хотите, чтобы сделать это по дате, то его проще - просто нужно outer apply:

select name,state,r.time, 
    gap = convert(int,isnull(r.time - x.time - 1,0)) 
from 
    MyTable r 
    outer apply (
     select top 1 time 
     from MyTable sub 
     where sub.time < r.time and sub.state = 1 
     order by sub.time desc) x 
where r.state = 1 

FYI тестовых данных используется была создана следующим образом:

create table MyTable 
(Name char(1), [state] tinyint, [Time] datetime) 

insert MyTable 
values 
('E',1,'2012-01-05'), 
('A',1,'2012-01-04'), 
('B',0,'2012-01-03'), 
('C',0,'2012-01-02'), 
('D',1,'2012-01-01') 
+0

блестящий, этот подход отлично работает. Благодарю. – Califf

Смежные вопросы