使用“Group Header”和Group Footer动态分组

问题描述 投票:-2回答:2

我有像qazxsw poi这样的类似问题。假设我们拥有与链接问题相同的示例数据。这里是相同的示例数据:

产品表

this question

产品销售

+-----------+-------------+------------+-------------+
| ProductId | ProductName | groupName  | parentGroup |
+-----------+-------------+------------+-------------+
|         1 | Orange      | fruit      | food        |
|         2 | Apple       | fruit      | food        |
|         3 | Cucumber    | vegetables | food        |
|         4 | Capsicum    | vegetables | food        |
+-----------+-------------+------------+-------------+

如果我想要小组的总数在底部怎么办?像这样的东西:

有没有一种方法可以将这些数据分组,如图所示,这非常动态?

非常感谢您的帮助!

sql sql-server tsql dynamic
2个回答
0
投票

确切地说,您的格式很棘手,应该可以在应用程序层完成。

但是,您可以使用+-----------+-------+ | ProductId | price | +-----------+-------+ | 1 | 5 | | 1 | 4 | | 2 | 2 | | 2 | 3 | | 2 | 3 | | 3 | 8 | | 3 | 6 | | 4 | 9 | | 4 | 9 | | 4 | 7 | | 4 | 10 | +-----------+-------+ 和我对该问题的答案来获得总数:

grouping sets

0
投票

老实说,我更多地将此作为个人挑战,但我认为它会告诉你戈登在你的申请层中应该处理这个问题时的正确性。

从技术上讲,这在纯SQL中是可行的。但这是一个非常糟糕的主意:

select which,
       coalesce(name, groupName + ' Total') as name
       sum(price)
from products p cross apply
     (values ('productName', productName),
             ('groupName', groupName),
             ('parentGroup', parentGroup)
     ) v(which, name) left join
     productsales ps
     on ps.productId = p.productId
group by grouping sets ( (which, name, groupName, parentGroup),
                         (which, groupName, parentGroup)
                       );

Output

declare @p table(ProductId int,ProductName varchar(20),groupName varchar(20),parentGroup varchar(20));
insert into @p values
 (1,'Orange','fruit','food')
,(2,'Apple','fruit','food')
,(3,'Cucumber','vegetables','food')
,(4,'Capsicum','vegetables','food');

declare @ps table(ProductId int,price int)
insert into @ps values
 (1,5)
,(1,4)
,(2,2)
,(2,3)
,(2,3)
,(3,8)
,(3,6)
,(4,9)
,(4,9)
,(4,7)
,(4,10);

with p as
(
    select distinct parentGroup
          ,'Start ' + parentGroup as label
    from @p
)
,g as
(
    select distinct groupName
          ,'Start ' + groupName as label
    from @p
)
,ru as
(
    select p.parentGroup
          ,p.groupName
          ,p.ProductName
          ,sum(ps.price) as Sales
    from @p as p
        left join @ps as ps
            on p.ProductId = ps.ProductId
    group by p.parentGroup
            ,p.groupName
            ,p.ProductName
    with rollup
)
,r as
(
    select row_number() over (order by parentGroup
                                      ,groupName
                                      ,ProductName
                              ) as rn
          ,Product
          ,Sales
          ,parentGroup
          ,groupName
          ,ProductName

    from (
        select isnull(isnull(ru.ProductName,g.groupName + ' Total'),ru.parentGroup + ' Total') as Product
              ,ru.Sales
              ,ru.parentGroup
              ,isnull(ru.groupName,'zzzzz') as groupName
              ,isnull(ru.ProductName,'zzzzz') as ProductName
              ,2 as sort
        from ru
            left join p
                on ru.parentGroup = p.parentGroup
            left join g
                on ru.groupName = g.groupName
        where ru.parentGroup is not null

        union all

        select isnull(g.label, p.label) as Product
              ,0 as Sales
              ,isnull(ru.parentGroup,'     ') as parentGroup
              ,isnull(ru.groupName,'     ') as groupName
              ,isnull(ru.ProductName,'     ') as ProductName
              ,1 as sort
        from ru
            left join p
                on ru.parentGroup = p.parentGroup
            left join g
                on ru.groupName = g.groupName
        where ru.ProductName is null
            and ru.parentGroup is not null
        ) as a
)
select Product
      ,Sales
from r
order by rn;
© www.soinside.com 2019 - 2024. All rights reserved.