I am trying to add row/column/grant totals (how many customers each of seller serviced and how many sellers each of customer had interacted with) for a dynamic pivot table in SQL query.
Since there are unknown numbers of sellers (columns in pivot table) in the actual data, I have to use dynamic pivot. I tried to use GROUP BY ROLLUP() and GROUP BY CUBE() but had failed to find the right place to fit them in. Any suggestion will be greatly appreciated!
Here is the sample data:
create table t
(
Id INT NOT NULL,
Customer varchar(5),
StartDay date,
Seller varchar(10)
);
insert into t values
(1, 'Bob', '1/4/2019', 'Joe'),
(1, 'Bob', '2/7/2021', 'Joe'),
(2, 'Kime', '8/9/2018', 'Tedy'),
(2, 'Kime', '1/11/2019', 'Tedy'),
(2, 'Kime', '10/1/2020', 'Anny'),
(3, 'Kelly', '10/1/2020', 'Angle'),
(4, 'Ben', '7/8/2020', 'Anny');
Here is the query with dynamic pivot table I have:
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX)
select @cols = STUFF((SELECT ',' + QUOTENAME(Seller)
from t
group by Seller
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query = N'SELECT Customer,' + @cols + N' from
(select Customer, Seller
from t
) x
pivot
( count(Seller)
for Seller in (' + @cols + N')
) p '
exec sp_executesql @query;
Below is my expected outcome:
Customer Angle Anny Joe Tedy Total
Ben 0 1 0 0 1
Bob 0 0 2 0 2
Kelly 1 0 0 0 1
Kime 0 1 0 2 3
Total 1 2 2 2 7 (Grand total)
3条答案
按热度按时间sgtfey8w1#
Here is a brute force approach ...
UNION ALL
Results
u1ehiz5o2#
You can use
GROUPING SETS
for this, which can be much easier than messing around withUNION ALL
. You can also combine that with a manual pivot usingCOUNT(CASE
db<>fiddle
cwtwac6a3#
John kinda beat me to it, but here's a bit more convoluted version that uses a few less UNIONs:
The difference is that i manually create Totals column by summarizing the other Pivots, as well as a bit more explicit sorting.
I also have to add that while this is doable in SQL, usually it's better to perform this sort of pivot in your application / reporting tool