TSQL - 与当前行不同的COUNT行数

时间:2012-06-19 22:26:10

标签: tsql select 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

加上一个额外的列'Skipped',其中包含状态0中state = 1的行之后的行数,换句话说输出应如下所示:

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
如果连续2个行处于state = 1状态,也应报告

0,即这些行之间没有任何状态处于1以外的状态。

似乎CTE必须在这里,但无法弄清楚如何计算状态!= 1的行。 任何帮助将不胜感激。

(MS Sql Server 2008)

2 个答案:

答案 0 :(得分:2)

我使用CTE建立RowNo,因此您不依赖于连续日期:

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')

答案 1 :(得分: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