SQL Server:按组标题分组和组总和和总和

时间:2014-08-20 22:01:46

标签: sql sql-server

我正在使用SQL Server 2012。

CREATE TABLE Table1
(
   Table2Id int,
   Stock int,
   Price money
);

INSERT INTO Table1 (Table2Id, Stock, Price) 
VALUES ('2','55','2');

INSERT INTO Table1 (Table2Id, Stock, Price)
VALUES ('2','46','3');

INSERT INTO Table1 (Table2Id, Stock, Price)
VALUES ('2','47','6');

INSERT INTO Table1 (Table2Id, Stock, Price)
VALUES ('2','45','4');

INSERT INTO Table1 (Table2Id, Stock, Price)
VALUES ('3','58','5');

INSERT INTO Table1 (Table2Id, Stock, Price)
VALUES ('3','51','1');

INSERT INTO Table1 (Table2Id, Stock, Price)
VALUES ('4','24','33');

INSERT INTO Table1 (Table2Id, Stock, Price)
VALUES ('4','53','72');

INSERT INTO Table1 (Table2Id, Stock, Price)
VALUES ('4','21','91');


CREATE TABLE Table2
(
   Id      int,
   Field1 varchar(5),
   Field2 varchar(5),
   Field3 varchar(5)
);

INSERT INTO Table2 (Id, Field1, Field2, Field3)
VALUES ('2','A','A1','A2');

INSERT INTO Table2 (Id, Field1, Field2, Field3)
VALUES ('3','B','B1','B2');

INSERT INTO Table2 (Id, Field1, Field2, Field3)
VALUES ('4','C','C1','C2');


SELECT 
   t1.Table2Id, t1.Price, t1.Stock,
   t2.Field1, t2.Field2, t2.Field3 
FROM 
   Table1 t1 
INNER JOIN 
   Table2 t2 ON t1.Table2Id = t2.Id
GROUP BY 
   t1.Table2Id, t1.Price, t1.Stock, t2.Field1, t2.Field2, t2.Field3

此查询结果为

Table2Id    Price           Stock       Field1      Field2      Field3 
2           2,00            55          A           A1          A2
2           3,00            46          A           A1          A2
2           4,00            45          A           A1          A2
2           6,00            47          A           A1          A2
3           1,00            51          B           B1          B2
3           5,00            58          B           B1          B2
4           33,00           24          C           C1          C2
4           72,00           53          C           C1          C2
4           91,00           21          C           C1          C2

但我想要这个结果。

        Table2Id    Price    Stock   Field1   Field2   Field3    GroupTotal   Total
G Header -> 2           NULL     NULL    A        A1       A2        NULL         NULL
            NULL        2,00     55      NULL     NULL     NULL      NULL         NULL
            NULL        3,00     46      NULL     NULL     NULL      NULL         NULL
            NULL        4,00     45      NULL     NULL     NULL      NULL         NULL
            NULL        6,00     47      NULL     NULL     NULL      NULL         NULL
G Footer -> NULL        NULL     NULL    NULL     NULL     NULL      15,00        NULL
G Header -> 3           NULL     NULL    B        B1       B2        NULL         NULL
            NULL        1,00     51      NULL     NULL     NULL      NULL         NULL
            NULL        5,00     58      NULL     NULL     NULL      NULL         NULL
G Footer -> NULL        NULL     NULL    NULL     NULL     NULL      6,00         NULL      
G Header -> 4           NULL     NULL    C        C1       C2        NULL         NULL
            NULL        33,00    24      NULL     NULL     NULL      NULL         NULL
            NULL        72,00    53      NULL     NULL     NULL      NULL         NULL
            NULL        91,00    21      NULL     NULL     NULL      NULL         NULL
G Footer -> NULL        NULL     NULL    NULL     NULL     NULL      196,00       NULL
Total F. -> NULL        NULL     NULL    NULL     NULL     NULL      NULL         217,00                

我怎样才能得到这个结果。

对我来说这是一个非常困难的问题。请帮我。

2 个答案:

答案 0 :(得分:0)

这里是分组的一般要点......

http://sqlfiddle.com/#!6/503fd/16/0

我使用了一个公用表表达式,所以我没有必要在整个地方玩这个价格的总和。

WITH CTE AS (SELECT t1.Table2Id, SUM(t1.Price) PRICE, t1.Stock,t2.Field1,t2.Field2,t2.Field3 
FROM Table1 t1 
INNER JOIN Table2 t2 
 ON t1.Table2Id=t2.Id
GROUP BY grouping sets 
((t1.Table2Id, t1.Price, t1.Stock,t2.Field1,t2.Field2,t2.Field3), 
 (t1.Table2Id),
 ()))
SELECT table2ID
, case when stock is null then null else price  end as Price
, Stock
, Field1
, Field2
, Field3
, Case when stock is null and table2ID is not null then price else null end as GroupTotal
, case when table2ID is null then Price else null end as Total
FROM CTE;

同样,这并不处理页眉/页脚行,但它确实处理了数值在正确列中的位置。

如果将其与Pivot结合使用......您可能能够实现标题分解;但是我很难看到它。

答案 1 :(得分:0)

为不同类型的行

创建4个单独的子查询

一个用于数据行 一个用于组头 一组为页脚 一个用于报告页脚

在每一个中都包含一个Rowtype列,因此每个列都应该返回列 RowType,Table2Id,Price,Stock,Field1,Field2,Field3,GroupTotal,Total

然后您可以使用UNION ALL子句将所有行放在一起,并使用Order by子句按顺序获取它们,

您可以在select语句的列列表中使用CASE语句,以便在需要时返回NULL

SELECT 
CASE WHEN d.RowType ='GH' THEN d.Table2Id ELSE NULL END as Table2Id,
CASE WHEN d.RowType ='D' THEN d.Price ELSE NULL END as Price,
CASE WHEN d.RowType ='D' THEN d.Stock ELSE NULL END as Stock,
CASE WHEN d.RowType ='GH' THEN d.Field1 ELSE NULL END as Field1,
CASE WHEN d.RowType ='GH' THEN d.Field2 ELSE NULL END as Field2,
CASE WHEN d.RowType ='GH' THEN d.Field3 ELSE NULL END as Field3,
CASE WHEN d.RowType ='GF' THEN d.Price ELSE NULL END as GroupTotal,
CASE WHEN d.RowType ='RF' THEN d.Price ELSE NULL END as Total
FROM 
(
SELECT 
'D' as RowType,
t1.Table2Id, t1.Price, t1.Stock,t2.Field1,t2.Field2,t2.Field3 FROM Table1 t1 INNER JOIN Table2 t2 ON t1.Table2Id=t2.Id
union all
SELECT 
'GH' as RowType,
 Table2Id,  0 as Price, 0 as Stock,t2.Field1,t2.Field2,t2.Field3 FROM Table1 t1 INNER JOIN Table2 t2 ON t1.Table2Id=t2.Id
GROUP BY Table2Id,t2.Field1,t2.Field2,t2.Field3 
union all
SELECT 
'GF' as RowType,
 Table2Id, SUM(PRice) as Price, 0 as Stock,NULL,NULL,NULL FROM Table1 t1 INNER JOIN Table2 t2 ON t1.Table2Id=t2.Id
GROUP BY Table2Id
union all
SELECT 
'RF' as RowType,
0 as Table2Id, SUM(PRice) as Price, 0 as Stock,null as Field1,null as Field2,null as Field3 FROM Table1 t1 INNER JOIN Table2 t2 ON t1.Table2Id=t2.Id
) d
ORDER BY 
CASE WHEN d.RowType = 'RF' then 1 ELSE 0 END,
 d.Table2Id,
CASE WHEN d.RowType = 'GH' then 0 
WHEN d.RowType = 'D' then 1
WHEN d.RowType = 'GF' then 2
ELSE 4 END