簡體   English   中英

計算SQL中的位列中的出現次數

[英]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;

sql小提琴演示

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM