[英]Count number of occurrences in a bit column in sql
如何計算sql server
列中的變化(如我有Ignition
值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 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 1 1 0 0 0 0 0 0 1
我只想統計從0到1發生1的變化。也可以從1到0將發生1的變化。
步驟1:根據我們的訂單,使用Row_Number()
函數提供完整的( 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:獲利!
不知道您是否想要一個同時具有2008年和2012年標簽的解決方案,但是在2012年(2008年不起作用)中,我們確實獲得了LAG()
和LEAD()
所以SUM()
為[Change]
在下面的查詢中將在2012年完成此操作。您必須決定如何處理第一個值(顯然沒有上一個值),當前狀態將被視為更改。
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;
對於2008年,自我加入應該產生相同的結果。
SELECT [T1].[Id]
, [T1].[Ignition]
, [T2].[Ignition] [Previous]
, CASE WHEN [T1].[Ignition] = [T2].[Ignition] THEN 0 ELSE 1 END [Change]
FROM [dbo].[Table] [T1]
LEFT JOIN [dbo].[Table] [T2] ON [T1].[Id] = ([T2].[Id] + 1)
ORDER BY [T1].[Id];
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
我知道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;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.