计算一列中非连续出现的值

时间:2019-04-10 23:20:56

标签: sql-server

我有下表:

ID   Value
1     X
1     Y
1     X
1     X
1     X
1     Y
1     X
2     X
2     Y
2     X
2     Z
2     Y
2     X

我需要计算每个ID出现X的非连续次数。 所以我的输出应该是:

ID    COUNT
1      3
2      3     

使用Select Count(*), ID From my_table where value = 'X'会计算每次出现的值,而不是仅计算非连续值。

我该如何解决?

2 个答案:

答案 0 :(得分:1)

首先,我在表中添加了一个标识列,该列将创建一个行号。 然后,我创建了第二个表,并创建RN-1以获取下一行并进行联接。 最后,我为Count值添加了条件。

DECLARE @tbl TABLE
(
    RN int IDENTITY(1,1),
    Id int,
    Value varchar(10)
)

INSERT INTO @tbl
Values (1,'X'),(1,'Y'),(1,'X'),(1,'X'),(1,'X'),(1,'Y'),(1,'X'),(2,'X'),(2,'Y'),(2,'X'),(2,'Z'),(2,'Y'),(2,'X')

SELECT A.Id1, SUM(A.XCount) AS Count
From(
SELECT RN1 =  t.RN, Id1 = t.Id, Value1 = t.Value, RN2 = t2.RN, Id2 = t2.Id, Value2 = t2.[Value], 
XCount = CASE WHEN t.[Value] = 'X' AND (t.[Value] != t2.[Value] OR t.[Id] != t2.[Id] OR t2.[Value] IS NULL)  THEN 1 ELSE 0 END 
    FROM @tbl t
    Left JOIN (SELECT RN = RN - 1 , Id, Value FROM @tbl ) as t2 ON t.RN = t2.RN
) A
GROUP BY A.Id1

答案 1 :(得分:1)

您可以将SQL Server的lag函数与最新版本一起使用来比较上一行中的值。下面的CTE构造了一个包含id, value, previousId, previousValue的表,第二部分对出现的次数进行了计数,其中value包含X,而先前的出现是不同的:

with cte as (
    select id, value,
    lag(id, 1, null) over (order by id, orderId) as previousId, 
    lag(value, 1, null) over (order by id, orderId) as previousValue from my_table
)
select id, count(*)
from cte
where value = 'X' and (id <> previousId or previousValue <> 'X' or previousValue is null)
group by id