【问题标题】:TSQL - COUNT number of rows in a different state than current rowTSQL - 与当前行处于不同状态的 COUNT 行数
【发布时间】:2012-06-22 01:09:11
【问题描述】:

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

表表:

 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 中 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 个连续的行处于状态 = 1,也应该报告 0,即这些行之间除了 1 之外没有任何东西。

CTE 似乎是必须的,但不知道如何计算 state != 1 的行数。 任何帮助将不胜感激。

(MS Sql Server 2008)

【问题讨论】:

    标签: tsql select count


    【解决方案1】:

    我使用 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')
    

    【讨论】:

      【解决方案2】:

      好的,给你(有点乱):

      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
      

      【讨论】:

        猜你喜欢
        • 2021-12-27
        • 1970-01-01
        • 2022-01-19
        • 2012-08-06
        • 1970-01-01
        • 1970-01-01
        • 2016-10-20
        • 2020-08-14
        • 1970-01-01
        相关资源
        最近更新 更多