在sql server中分组

Grouping in sqlserver

我有类似于 below.I 的数据需要根据数据的出现对状态列进行分组。

Id  Status  Value
1     K      1
2     K      3
3     K      2
4     B      2
5     B      3
6     K      6
7     J      5
8     J      2

我要如下数据

Status  Value
K       6
B       5
K       6
J       7

我需要累加值 column.In status 列如果数据连续相同,那么我需要添加 value 列。我无法应用组 by.In 给定 K 的示例重复了两次,因为它们不是连续的。

我试过下面的查询,但没有按要求工作。

select Status,
       (select sum(value)
        from table t2
        where 
          t2.Status = t.Status and
           t2.SNO <= t.SNO
       ) as total

from table t;

请帮忙!!

这是一个差距和孤岛问题

我通过使用递增的 Id 并将其与 ROW_NUMBER window 函数

相结合来解决这些问题
--Using a CTE just to replicate the sample data
;WITH cteX (Id,Status,Value)
AS(
    SELECT 1,'K', 1 UNION ALL
    SELECT 2,'K', 3 UNION ALL
    SELECT 3,'K', 2 UNION ALL
    SELECT 4,'B', 2 UNION ALL
    SELECT 5,'B', 3 UNION ALL
    SELECT 6,'K', 6 UNION ALL
    SELECT 7,'J', 5 UNION ALL
    SELECT 8,'J', 2
)
SELECT
      Grp = Id - ROW_NUMBER()OVER( PARTITION BY X.Status ORDER BY X.Id) 
    , X.Id
    , X.Status
    , X.Value
FROM 
    cteX X
ORDER BY
    X.Id

这给出了这个结果集,注意 Grp 列

Grp     Id      Status  Value
------- ------- ------- -------
0       1       K       1
0       2       K       3
0       3       K       2
3       4       B       2
3       5       B       3
2       6       K       6
6       7       J       5
6       8       J       2

然后结合 CTE 或派生的 table 您可以获得预期的输出

--Using a CTE just to replicate the sample data
;WITH cteX (Id,Status,Value)
AS(
    SELECT 1,'K', 1 UNION ALL
    SELECT 2,'K', 3 UNION ALL
    SELECT 3,'K', 2 UNION ALL
    SELECT 4,'B', 2 UNION ALL
    SELECT 5,'B', 3 UNION ALL
    SELECT 6,'K', 6 UNION ALL
    SELECT 7,'J', 5 UNION ALL
    SELECT 8,'J', 2
)
SELECT Y.Status
     , Value = SUM(Y.Value)
FROM
(
    SELECT TOP 100 PERCENT
          Grp = Id - ROW_NUMBER()OVER( PARTITION BY X.Status ORDER BY X.Id) 
        , X.Id
        , X.Status
        , X.Value
    FROM 
        cteX X
    ORDER BY
        X.Id
) Y
GROUP BY
    Y.Grp, Y.Status

输出

Status  Value
------- -------
B       5
J       7
K       6
K       6

更新问题包括"Preserve order"解决方案

只需包含一个 Order by MIN(Id)

--Using a CTE just to replicate the sample data
;WITH cteX (Id,Status,Value)
AS(
    SELECT 1,'K', 1 UNION ALL
    SELECT 2,'K', 3 UNION ALL
    SELECT 3,'K', 2 UNION ALL
    SELECT 4,'B', 2 UNION ALL
    SELECT 5,'B', 3 UNION ALL
    SELECT 6,'K', 6 UNION ALL
    SELECT 7,'J', 5 UNION ALL
    SELECT 8,'J', 2
)
    SELECT 
         Y.[Status]
        ,[Value] = SUM(Y.[Value])
    FROM
    (
        SELECT
              Grp = Id - ROW_NUMBER()OVER( PARTITION BY X.[Status] ORDER BY X.Id) 
            , X.Id
            , X.[Status]
            , X.[Value]
        FROM 
            cteX X
    ) Y
    GROUP BY
        Y.Grp, Y.[Status]
    ORDER BY
        MIN(Y.Id) --preserve the Status Order

输出

Status  Value
------- -------
K       6
B       5
K       6
J       7