一组中的小计

时间:2016-09-22 08:54:00

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

我有一个按地名和yyyy-mm分组的查询。我想要的是每个月共有3个地名的总和。例如,在下面看3个地方的总数' for' total1'在3月将是14,4 + 5 + 5

   place         yyyy-mm         total1       total2     total3
     A           2016-03           4            4          5
     B           2016-03           5            1          2
     C           2016-03           5            4          2
     A           2016-04           1            3          4
     B           2016-04           2            3          4
     C           2016-04           6            2          1 

这样的事情

    place       yyyy-mm         total1       total2     total3
     A           2016-03           4            4          5
     B           2016-03           5            1          2
     C           2016-03           5            4          2
     ALL         2016-03           14           9          9
     A           2016-04           1            3          4
     B           2016-04           2            3          4
     C           2016-04           6            2          1 
     ALL         2016-04           9            8          9

4 个答案:

答案 0 :(得分:3)

您可以使用GROUP BY GROUPING SETS

CREATE TABLE #MyTable( Place VARCHAR(10), Date VARCHAR(20), Total1 INT, Total2 INT, Total3 INT ) 

INSERT INTO #MyTable ( place, [date], Total1, Total2, Total3 )
VALUES(      'A',           '2016-03' ,          4,            4 ,         5 )
      , ( 'B',           '2016-03',           5,           1,          2)
      , ( 'C',           '2016-03',           5,           4,          2)
      , ( 'A',           '2016-04',           1,           3,          4)
      , ( 'B',           '2016-04',           2,           3,          4)
      , ( 'C',           '2016-04',           6,           2,          1)


SELECT  
   [Date]
   , ISNULL( Place  , 'Total' )
   , SUM( Total1 ) AS Total1
   , SUM( Total2 ) AS Total2
   , SUM( Total3 ) AS Total3
FROM #MyTable
GROUP BY GROUPING SETS
 ( Place, [Date] )
, ( [Date] ) 


DROP TABLE #MyTable

答案 1 :(得分:2)

您也可以使用union all,但汇总在可读性和性能方面更好(不访问表两次)

SELECT 
CASE WHEN PLACE IS NULL THEN 'ALL' ELSE  PLACE END as place,
YYYYMM,
SUM(TOTAL1) AS TOTAL1,SUM(TOTAL2) AS TOTAL2,SUM(TOTAL3) AS TOTAL3
FROM #TEMP
GROUP BY YYYYMM,PLACE
WITH ROLLUP
HAVING GROUPING(YYYYMM)=0

输出:

place   YYYYMM  TOTAL1  TOTAL2  TOTAL3
A       2016-03    4      4       5
B       2016-03    5      1       2
C       2016-03    5      4       2
ALL     2016-03    14     9       9
A       2016-04    1      3       4
B       2016-04    2      3       4
C       2016-04    6      2       1
ALL     2016-04    9      8       9

答案 2 :(得分:2)

使用分组依据ROLLUP

DECLARE @tblTest AS Table(
    Place VARCHAR(5),
    YearMonth DATE,
    Total1 INT,
    Total2 INT,
    Total3 INT
)

INSERT INTO @tblTest VALUES
('A','2016-03-01',4,4,5),
('B','2016-03-01',5,1,2),
('C','2016-03-01',5,4,2),
('A','2016-04-01',1,3,4),
('B','2016-04-01',2,3,4),
('C','2016-04-01',6,2,1)

;with X AS
(
    SELECT
        Place,
        YearMonth,         
        SUM(Total1) AS Total1,
        SUM(Total2) AS Total2,
        SUM(Total3) AS Total3
    FROM @tblTest
    GROUP BY YearMonth,Place WITH ROLLUP
)
SELECT
    CASE ISNULL(Place,'') WHEN '' THEN 'ALL' ELSE Place END AS Place,
    YearMonth, 
    Total1,
    Total2,
    Total3
FROM X
WHERE X.YearMonth IS NOT NULL

<强>输出:

enter image description here

答案 3 :(得分:2)

这可以通过使用GROUPING SETS来实现。

<强>查询

select 
    coalesce([place], 'ALL') as [place], 
    [yyyy-mm], 
    sum([total1]) as [total1], 
    sum([total2]) as [total2],
    sum([total3]) as [total3]
from [your_table_name]
group by grouping sets(([place], [yyyy-mm]), ([yyyy-mm]));

Find a demo here