简体   繁体   中英

Counting how many times a boolean value changes in SQL Server

I have this table:

     [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

I need a query to count how many times the value changes.

For example:

    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

You can do this with lag() :

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

This should work in earlier versions too..

;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 

Pre-SQL Server 2012 solution:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM