如何计算sql server
列中的更改,例如我有Ignition
值
点火
1
1
0
1
1
1
0
0
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
1
1
0
0
0
0
0
0
1
我想计算更改只是从0到1才能生成1。它也可以从1到0表示事件为1.
答案 0 :(得分:2)
第1步:根据我们的订单,使用Row_Number()
函数提供完整(未破损)的数字序列
SELECT ignition
, id
, Row_Number() OVER (ORDER BY id ASC) As row_num
FROM your_table
第4步:将其设为公用表表达式(CTE),以便我们可以参考派生的row_num
列
; WITH cte AS (
SELECT ignition
, id
, Row_Number() OVER (ORDER BY id ASC) As row_num
FROM your_table
)
SELECT ignition
, id
, row_num
FROM cte
第3步:将此表连接回自己在下一行/上一行的匹配
; WITH cte AS (
SELECT ignition
, id
, Row_Number() OVER (ORDER BY id ASC) As row_num
FROM your_table
)
SELECT c1.ignition As c1_ignition
, c2.ignition As c2_ignition
FROM cte As c1
LEFT
JOIN cte As c2
ON c2.row_num = c1.row_num + 1
第4步:过滤结果以显示值不相同的结果
; WITH cte AS (
SELECT ignition
, id
, Row_Number() OVER (ORDER BY id ASC) As row_num
FROM your_table
)
SELECT c1.ignition As c1_ignition
, c2.ignition As c2_ignition
FROM cte As c1
LEFT
JOIN cte As c2
ON c2.row_num = c1.row_num - 1
WHERE c1.ignition <> c2.ignition
第5步: ...
第6步:获利!
答案 1 :(得分:1)
不确定您是否想要一个既适用于2008年又适用于2012年的解决方案,但是在2012年(在2008年无效)我们确实得到了LAG()
和LEAD()
所以在下面的查询中,SUM()
的{{1}}将在2012年执行此操作。您必须决定如何处理第一个值(显然没有先前的值),当前状态计为改变。
[Change]
对于2008年,自我加入应产生相同的结果。
SELECT [Id]
, [Ignition]
, LAG([Ignition]) OVER(ORDER BY [Id]) [Previous]
, CASE WHEN LAG([Ignition]) OVER(ORDER BY [Id]) = [Ignition] THEN 0 ELSE 1 END [Change]
FROM [dbo].[Table]
ORDER BY Id;
答案 2 :(得分:0)
declare @t table(id int identity(1,1), ignition bit)
insert @t values(1),(0),(1),(1)
declare @Ignition varchar(max) = ''
select @Ignition = @Ignition + cast(Ignition as char(1))
from @t order by id
select @ignition
select len(replace(replace(replace(@Ignition, '10', 'x')
+ replace(@Ignition, '01', 'x'), 1, ''), 0, ''))
结果:
2
答案 3 :(得分:-2)
我知道SQL Server 2008的最简单和最短的方法是:
with cte as (
select
row_number() over(partition by Ignition order by Id) as rn1,
row_number() over(order by Id) as rn2
from Table1
)
select count(distinct rn2 - rn1) - 1
from cte
或者,正如@MartinSmith指出的那样:
with cte as (
select
row_number() over(order by Ignition, Id) as rn1,
row_number() over(order by Id) as rn2
from Table1
), cte2 as (
select distinct Ignition, rn2 - rn1
from cte
)
select count(*) - 1
from cte2
对于SQL Server 2012,您可以使用lag()(或lead())函数:
;with cte as (
select
lag(Ignition) over(order by Id) as prev,
Ignition as cur
from Table1
)
select count(case when cur <> prev then 1 end)
from cte;
<强> sql fiddle demo 强>