【问题标题】:Count Non-Consecutive occurrences of value in a column计算列中值的非连续出现次数
【发布时间】:2019-09-01 12:06:52
【问题描述】:

我有下表:

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' 计算每次出现的值,而不是仅计算非连续值。

我该如何解决这个问题?

【问题讨论】:

  • 不是您的问题的答案,但在您提出这样的问题之前您可能需要了解一些内容:stackoverflow.com/a/20050403/5552667
  • 感谢 ZLK。所以现在即使我在查询中添加 ORDER BY ID,它仍然会返回计数 X 的所有值,而不是只计算非连续值。我该如何克服这个问题。
  • 对不起,如果不清楚,但这里的“连续”和“非连续”的概念是不正确的。字母没有明确的顺序。您看到的默认顺序可以因各种原因而改变。您可以尝试执行SELECT ID, COUNT(DISTINCT RN) FROM (SELECT *, RN = ROW_NUMBER() OVER (PARTITION BY ID ORDER BY (SELECT NULL)) - ROW_NUMBER() OVER (PARTITION BY ID, Value ORDER BY (SELECT NULL)) FROM my_table) AS T GROUP BY ID; 之类的操作,但无论是否返回准确的结果,将来都可能不会产生准确的结果。

标签: sql-server


【解决方案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

【讨论】:

    【解决方案2】:

    首先我在表中添加了一个标识列,它将创建一个行号。 然后我创建了第二个表并 Make 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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-16
      • 1970-01-01
      相关资源
      最近更新 更多