Sql 使用“动态分组;组头”;和组页脚

Sql 使用“动态分组;组头”;和组页脚,sql,sql-server,tsql,dynamic,Sql,Sql Server,Tsql,Dynamic,我也有类似的问题。假设我们有与链接问题相同的示例数据。以下是相同的示例数据: 产品表 +-----------+-------------+------------+-------------+ | ProductId | ProductName | groupName | parentGroup | +-----------+-------------+------------+-------------+ | 1 | Orange | fruit | f

我也有类似的问题。假设我们有与链接问题相同的示例数据。以下是相同的示例数据:

产品表

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

+-----------+-------+
| ProductId | price |
+-----------+-------+
|         1 |     5 |
|         1 |     4 |
|         2 |     2 |
|         2 |     3 |
|         2 |     3 |
|         3 |     8 |
|         3 |     6 |
|         4 |     9 |
|         4 |     9 |
|         4 |     7 |
|         4 |    10 |
+-----------+-------+
如果我想把小组的总数排在最后怎么办。大概是这样的:

是否有一种方法可以将这些数据按图片中的方式进行分组,并非常动态地进行分组


非常感谢您的帮助

确切地说,您的格式很复杂,可能应该在应用程序层完成

但是,您可以在我对该问题的回答中使用
分组集
,以获得总数:

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)
                       );

老实说,我这样做更多的是作为个人的挑战,但我认为这将向您展示Gordon是多么正确,他说您应该在应用程序层中处理这一点

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

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;
输出
请删除指向外部数据的链接,而是将所有相关数据直接包含在问题中。链接可以而且确实会随着时间的推移而中断,如果你也希望本网站的用户也会尝试帮助你,那么你应该准备花几分钟来格式化你的问题。简单看看这些图片,我看不出这需要动态。看起来它只是需要一些聚合。到目前为止你试过什么了吗?这里有一个很好的资源,可以根据需要提供。你好,Larnu,问题是这只是示例数据。我不能公布真实的数据。我的真实数据中有几个“组名”。上面链接的问题确实很有帮助,但我不知道如何添加“Groupfooter”,正如您在截图中看到的那样。非常感谢您的努力。如你所知。我对这东西真的很陌生。所以您建议,我应该在我的Web API应用程序中这样做。除了复杂的SQL代码之外,还有什么具体的原因吗?在C#中这样做更简单吗?在表示层中添加页眉和页脚应该更容易,并且考虑到复杂性方面的节省可能也更快。至于如何做到这一点,这将完全取决于您的表示层是什么,以及您的数据是如何提供给它的。为此,我建议你尝试一下,如果你陷入困境,可以问一些新问题。非常感谢你的努力。如你所知。我对这东西真的很陌生。所以您建议,我应该在我的Web API应用程序中这样做。除了复杂的SQL代码之外,还有什么具体的原因吗?
+------------------+-------+
|     Product      | Sales |
+------------------+-------+
| Start food       |     0 |
| Start fruit      |     0 |
| Apple            |     8 |
| Orange           |     9 |
| fruit Total      |    17 |
| Start vegetables |     0 |
| Capsicum         |    35 |
| Cucumber         |    14 |
| vegetables Total |    49 |
| food Total       |    66 |
+------------------+-------+