GROUP BY с частичным ROLLUP - PullRequest
2 голосов
/ 12 февраля 2020

Я не могу описать мою проблему, но я подготовил пример.

Это мой запрос:

SELECT
 level1id, level1desc, level2id, level2desc, level3id, level3desc, level4id, level4desc, SUM(amount * price) AS turnover
FROM productgrouptree pgt
INNER JOIN sales s ON s.productgroupid = pgt.level4id
GROUP BY ROLLUP (level1id, level1desc, level2id, level2desc, level3id, level3desc, level4id, level4desc)
--GROUP BY ROLLUP (level1id, level2id, level3id, level4id), level1desc, level2desc, level3desc, level4desc
--GROUP BY GROUPING SETS (level1id, level1desc, level2id, level2desc, level3id, level3desc, level4id, level4desc)
--GROUP BY GROUPING SETS (level1id, level2id, level3id, level4id), level1desc, level2desc, level3desc, level4desc
--GROUP BY GROUPING SETS (ROLLUP (level1id, level2id, level3id, level4id), level1desc, level2desc, level3desc, level4desc)
--GROUP BY GROUPING SETS (ROLLUP (level1id, level1desc, level2id, level2desc, level3id, level3desc, level4id, level4desc))
--GROUP BY GROUPING SETS (ROLLUP (level1id, level1desc), ROLLUP(level2id, level2desc), ROLLUP(level3id, level3desc), ROLLUP(level4id, level4desc))
ORDER BY level1id, level2id, level3id, level4id

Это мой желаемый результат:

desired result

И вот SQL для создания примера:

create table productgrouptree (
 level1id int not null,
 level1desc varchar(100) not null,
 level2id int not null,
 level2desc varchar(100) not null,
 level3id int not null,
 level3desc varchar(100) not null,
 level4id int not null,
 level4desc varchar(100) not null
)

insert into productgrouptree values
(10, 'Level1-10', 1010, 'Level2-1010', 101010, 'Level3-101010', 10101010, 'Level4-10101010'),
(10, 'Level1-10', 1010, 'Level2-1010', 101010, 'Level3-101010', 10101020, 'Level4-10101020'),
(20, 'Level1-20', 2010, 'Level2-2010', 201010, 'Level3-201010', 20101030, 'Level4-20101030')

create table sales (
 salesid int not null constraint sales_pk primary key,
 productid int not null,
 productgroupid int not null,
 amount int not null,
 price decimal(10,2) not null
)

insert into sales values
(1, 1, 10101010, 3, 17.99),
(2, 2, 10101020, 6, 89.99),
(3, 3, 20101030, 9, 39.99),
(4, 1, 10101010, 3, 17.99)

Возможно ли это?

Ответы [ 2 ]

1 голос
/ 12 февраля 2020

Этот запрос соответствует вашим потребностям:

SELECT  level1id, 
        IIF(level1id IS NULL, NULL, MIN(level1desc)) AS level1desc,
        level2id,
        IIF(level2id IS NULL, NULL, MIN(level2desc)) AS level2desc,
        level3id,
        IIF(level3id IS NULL, NULL, MIN(level3desc)) AS level3desc,
        level4id,
        IIF(level4id IS NULL, NULL, MIN(level4desc)) AS level4desc,
        SUM(amount * price) AS turnover
FROM productgrouptree pgt
INNER JOIN sales s ON s.productgroupid = pgt.level4id
GROUP BY ROLLUP (level1id, level2id, level3id, level4id)
ORDER BY level1id, level2id, level3id, level4id
0 голосов
/ 12 февраля 2020

Вы можете использовать grouping_id () для фильтрации уровней агрегации:

SELECT
 level1id, level1desc, level2id, level2desc, level3id, level3desc, level4id, level4desc, SUM(amount * price) AS turnover,
 grouping_id(level1id, level1desc, level2id, level2desc, level3id, level3desc, level4id, level4desc)
FROM productgrouptree pgt
INNER JOIN sales s ON s.productgroupid = pgt.level4id
GROUP BY ROLLUP (level1id, level1desc, level2id, level2desc, level3id, level3desc, level4id, level4desc)
having grouping_id(level1id, level1desc, level2id, level2desc, level3id, level3desc, level4id, level4desc) in (0, 3, 15, 63, 255)
ORDER BY level1id, level2id, level3id, level4id;
...