计算SQL Server中布尔值更改的次数

时间:2014-11-09 14:57:43

标签: sql tsql sql-server-2012

我有这张桌子:

     [SDate - DateTime]                 [Value] - Represents a boolean
    2010-11-16 10:10:00                    1
    2010-11-16 10:11:00                    0
    2010-11-16 10:12:00                    1
    2010-11-16 10:13:00                    1

我需要一个查询来计算值变化的次数。

例如:

    2010-11-16 10:10:00                    0
    2010-11-16 10:11:00                    1
    2010-11-16 10:12:00                    0
    2010-11-16 10:13:00                    0
    2010-11-16 10:14:00                    1
    2010-11-16 10:15:00                    0
    2010-11-16 10:16:00                    1
    ...
                                       5 changes

    2010-11-16 10:10:00                    0
    2010-11-16 10:11:00                    0
    2010-11-16 10:12:00                    0
    2010-11-16 10:13:00                    1
    2010-11-16 10:14:00                    1
    2010-11-16 10:15:00                    1
    2010-11-16 10:16:00                    1
    ...                                       
                                        1 change

3 个答案:

答案 0 :(得分:8)

您可以使用lag()

执行此操作
select count(*)
from (select t.*, lag(value) order by (sdate) as prev_value
      from table t
     ) t
where prev_value <> value ;

答案 1 :(得分:2)

这也适用于早期版本..

;WITH cte
     AS (SELECT Row_number()OVER(ORDER BY sdates) rn,*
         FROM   <tablename>)
SELECT Sum(CASE WHEN a.boolvalue = b.boolvalue THEN 0 ELSE 1 END)
FROM   cte a
       JOIN cte b
         ON a.rn = b.rn + 1 

答案 2 :(得分:1)

Pre-SQL Server 2012解决方案:

declare @t table ( sdate datetime, value int )

insert into @t(sdate, value)
values
--('2010-11-16 10:10:00', 0),
--('2010-11-16 10:11:00', 1),
--('2010-11-16 10:12:00', 0),
--('2010-11-16 10:13:00', 0),
--('2010-11-16 10:14:00', 1),
--('2010-11-16 10:15:00', 0),
--('2010-11-16 10:16:00', 1)
('2010-11-16 10:10:00', 0),
('2010-11-16 10:11:00', 0),
('2010-11-16 10:12:00', 0),
('2010-11-16 10:13:00', 1),
('2010-11-16 10:14:00', 1),
('2010-11-16 10:15:00', 1),
('2010-11-16 10:16:00', 1)


;with t_with_seq as (
  select 
    t.*,
    ROW_NUMBER() OVER(ORDER BY t.sdate asc) as seq
  from @t t
)
select 
  COUNT(*) 
from t_with_seq r
  inner join t_with_seq r_next on r_next.seq = r.seq + 1
where r.value <> r_next.value