Динамически группируется с помощью «Верхний колонтитул группы» и Нижний колонтитул группы - PullRequest
0 голосов
/ 11 марта 2019

У меня похожая проблема, такая как этот вопрос . Предположим, у нас есть те же данные примера, что и из связанного вопроса. Вот те же данные примера:

Таблица продуктов

+-----------+-------------+------------+-------------+
| 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 |
+-----------+-------+

Что делать, если я хочу общее количество группы внизу. Примерно так:

Есть ли способ, которым я могу сгруппировать эти данные, как на картинке, и это очень динамично?

Заранее большое спасибо за помощь!

Ответы [ 2 ]

0 голосов
/ 11 марта 2019

Честно говоря, я сделал это больше как личный вызов, но я думаю, что это показывает, насколько прав Гордон, когда он заявляет, что вы должны справиться с этим на уровне приложений.

С технической точки зрения это возможно вчистый 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;

Вывод

+------------------+-------+
|     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 |
+------------------+-------+
0 голосов
/ 11 марта 2019

Точно ваш формат сложен и, вероятно, должен быть сделан на прикладном уровне.

Однако вы можете использовать grouping sets с моим ответом на этот вопрос, чтобы получить итоговые значения:

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)
                       );
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...