如何仅对表中的字段进行分组,直到它更改值(SQL Server)

时间:2016-05-18 09:42:13

标签: sql sql-server sql-server-2012

我有下表'ProductTable'

Product   | Series | Date  
  aaa     | a1     | 2016-05-17 08:02:54.960 
  aaa     | a1     | 2016-05-17 08:03:54.960
  aaa     | a1     | 2016-05-17 08:04:54.960
  bbb     | b1     | 2016-05-17 08:05:54.960
  bbb     | b1     | 2016-05-17 08:06:54.960
  aaa     | a1     | 2016-05-17 08:07:54.960
  aaa     | a1     | 2016-05-17 08:08:54.960

我尝试了google的几个步骤并发现了一些名为row_number() over的内容,但未能使用它获得确切的结果,因为我是SQL SERVER的新手。我希望结果是这样的 - >

Product   | Series | Qty |  Cumml.
  aaa     | a1     | 3   |    3
  bbb     | b1     | 2   |    5
  aaa     | a1     | 2   |    7

如何进行这种性质的分组?请帮帮....

2 个答案:

答案 0 :(得分:1)

这是一个标准的孤岛解决方案,具有累积和的一些窗口聚合函数:

DECLARE @p TABLE
    (
      Product CHAR(3) ,
      Date DATETIME
    )
INSERT  INTO @p
VALUES  ( 'aaa', '2016-05-17 08:02:54.960' ),
        ( 'aaa', '2016-05-17 08:03:54.960' ),
        ( 'aaa', '2016-05-17 08:04:54.960' ),
        ( 'bbb', '2016-05-17 08:05:54.960' ),
        ( 'bbb', '2016-05-17 08:06:54.960' ),
        ( 'aaa', '2016-05-17 08:07:54.960' ),
        ( 'aaa', '2016-05-17 08:08:54.960' );
WITH    cte
          AS ( SELECT   * ,
                        ROW_NUMBER() OVER ( ORDER BY date )
                        - ROW_NUMBER() OVER ( PARTITION BY Product ORDER BY Date ) AS rn
               FROM     @p
             )
    SELECT  rn ,
            product ,
            COUNT(*) AS Cnt,
            SUM(COUNT(*)) OVER ( ORDER BY MAX(Date) ) AS Cumul
    FROM    cte
    GROUP BY rn ,
            product
    ORDER BY Cumul

输出:

rn  product Cnt Cumul
0   aaa     3   3
3   bbb     2   5
2   aaa     2   7

答案 1 :(得分:1)

请试试这个。它与SQL Server 2012一起正常工作。

DROP TABLE #Temp
CREATE TABLE #Temp
(
  Product Varchar(5) ,
  Series Varchar(5),
  Date DATETIME
)
INSERT  INTO #Temp
VALUES  ( 'aaa','a1', '2016-05-17 08:02:54.960' ),
        ( 'aaa','a1','2016-05-17 08:03:54.960' ),
        ( 'aaa','a1', '2016-05-17 08:04:54.960' ),
        ( 'bbb','b1', '2016-05-17 08:05:54.960' ),
        ( 'bbb','b1', '2016-05-17 08:06:54.960' ),
        ( 'aaa','a1', '2016-05-17 08:07:54.960' ),
        ( 'aaa','a1', '2016-05-17 08:08:54.960' )
;WITH    cte
      AS ( SELECT   * ,
                    ROW_NUMBER() OVER ( ORDER BY Date )
                    - ROW_NUMBER() OVER ( PARTITION BY Product ORDER BY Date ) AS rn
           FROM     #Temp
         )
SELECT
        Product ,Series,
        COUNT(*) OVER ( ORDER BY Product ) AS Cnt,
        SUM(COUNT(*)) OVER ( ORDER BY MAX(Date) ) AS cumml
FROM    cte
GROUP BY rn ,Product,Series
Order BY cumml