2

这有点难以解释,但从这个例子中应该很清楚。

表表:

 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

加上一个附加列“已跳过”,其中包含状态 0 中状态 = 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 个连续的行处于状态 = 1,也应该报告 0,即这些行之间除了 1 之外没有任何东西。

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

(MS Sql 服务器 2008)

4

2 回答 2

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

仅供参考,使用的测试数据创建如下:

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')
于 2012-06-19T23:12:44.990 回答
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
于 2012-06-19T23:00:59.793 回答