Sql 在一组未更改的值中聚合

Sql 在一组未更改的值中聚合,sql,sql-server-2012,Sql,Sql Server 2012,我有样本数据: RowId TypeId Value 1 1 34 2 1 53 3 1 34 4 2 43 5 2 65 6 16 54 7 16 34 8 1 45 9 6 43 10 6 34 11 16 64 12 16

我有样本数据:

RowId TypeId Value
    1      1    34
    2      1    53
    3      1    34
    4      2    43
    5      2    65
    6     16    54
    7     16    34
    8      1    45
    9      6    43
   10      6    34
   11     16    64
   12     16    63
我想计算每种类型的行数。该值对我来说并不重要,但仅对。。。邻居类型ID

TypeId Count
     1     3
     2     2 
    16     2
     1     1
     6     2
    16     2

如何实现此结果?

这将为您提供一组不变值中的行数:

SELECT TypeId, grp, COUNT(*) FROM (
  SELECT RowId, TypeId , Value, gap, SUM(gap) over (ORDER BY RowId ) grp
  FROM (SELECT RowId, TypeId , Value,
                CASE WHEN TypeId = lag(TypeId) over (ORDER BY RowId )
                   THEN 0
                   ELSE 1
                END gap 
        FROM dummy
    ) t
) tt
GROUP BY TypeId, grp;
如果您更喜欢包含无限子查询,请执行以下操作:

WITH dummy_with_groups AS (
  SELECT RowId, TypeId , Value, SUM(gap) OVER (ORDER BY RowId) grp
  FROM (SELECT RowId, TypeId , Value,
          CASE WHEN TypeId = lag(TypeId) OVER (ORDER BY RowId)
          THEN 0 ELSE 1 END gap 
        FROM dummy) t
)
SELECT TypeId, COUNT(*) as Result 
FROM dummy_with_groups
GROUP BY TypeId, grp;
看看这个。我给你的专栏重新命名了一点

WITH myCTE AS
         (SELECT row_id,
                 type_id,
                 ROW_NUMBER () OVER (PARTITION BY type_id ORDER BY row_id)
                     AS cnt,
                 CASE LEAD (type_id) OVER (ORDER BY row_id)
                     WHEN type_id THEN 0
                     ELSE 1
                 END
                     AS show
            FROM dummy),
     innerQuery AS
         (SELECT row_id, type_id, cnt
            FROM myCTE
           WHERE show = 1)
SELECT iq1.type_id, iq1.cnt - ISNULL (iq2.cnt, 0) CNT
  FROM innerQuery iq1
       LEFT OUTER JOIN innerQuery iq2
           ON     iq1.type_id = iq2.type_id
              AND EXISTS
                      (SELECT 1
                         FROM innerQuery iq3
                        WHERE     iq3.type_id = iq1.type_id
                              AND iq3.row_id < iq1.row_id
                       HAVING MAX (iq3.row_id) = iq2.row_id)

输出与预期完全一致。

当按rowid排序时,您可以与我们共享SQLNexter的确切版本吗?您可以使用LAG函数创建一个字段来标识每个组:这并不重要,但rowid总是连续的吗?参见Giannis的评论,它的sql server 2012。是的,按照“RowId”的顺序,输出是:3,2,2,4,2,4,它应该是:3,2,2,1,2,2,我得到了不正确的语法接近-接近上一个很好的计算,但不幸的是重新排序。6应该低于前16个。更新了答案,这样结果就不会被改变。经过短暂的考虑,我认为您的解决方案更好,速度更快。尤其是第二个。