dynamic创build列sql

我有一张顾客的桌子

Customer ID Name 1 John 2 Lewis 3 Mary 

我有另一个表CustomerRewards

  TypeID Description 1 Bronze 2 Silver 3 Gold 4 Platinum 5 AnotherOne 

和决赛桌

  RewardID TypeID CustomerID 1 1 1 2 1 1 3 2 1 4 2 2 

customerTypes表是dynamic的,这些types中的许多可以被添加和删除。 基本上我想要的是dynamic生成的列和每个类似的数量

 CustomerName Bronze Silver Gold Platinum AnotherOne total John 2 1 0 0 0 3 Lewis 0 1 0 0 0 1 Grand TOTAL 2 2 0 0 0 4 

像我说的问题,types是dynamic的,客户是dynamic的,所以我需要列dynamic取决于系统中的types

我已经标记了C#,因为我需要在DataGridView中

提前致谢

你会想为此使用一个PIVOTfunction。 如果您有已知数量的列,则可以对这些值进行硬编码:

 select name, [Bronze], [Silver], [Gold], [Platinum], [AnotherOne] from ( select c.name, cr.description, r.typeid from customers c left join rewards r on c.id = r.customerid left join customerrewards cr on r.typeid = cr.typeid ) x pivot ( count(typeid) for description in ([Bronze], [Silver], [Gold], [Platinum], [AnotherOne]) ) p; 

看演示与SQL小提琴 。

现在如果你有一个未知数量的列,那么你可以使用dynamicSQL来PIVOT

 DECLARE @cols AS NVARCHAR(MAX), @query AS NVARCHAR(MAX) select @cols = STUFF((SELECT ',' + QUOTENAME(description) from customerrewards group by description, typeid order by typeid FOR XML PATH(''), TYPE ).value('.', 'NVARCHAR(MAX)') ,1,1,'') set @query = 'SELECT name,' + @cols + ' from ( select c.name, cr.description, r.typeid from customers c left join rewards r on c.id = r.customerid left join customerrewards cr on r.typeid = cr.typeid ) x pivot ( count(typeid) for description in (' + @cols + ') ) p ' execute(@query) 

请参阅SQL小提琴演示

如果您需要包含Total列,那么您可以使用ROLLUP ( 静态版本演示 ):

 select name, sum([Bronze]) Bronze, sum([Silver]) Silver, sum([Gold]) Gold, sum([Platinum]) Platinum, sum([AnotherOne]) AnotherOne from ( select name, [Bronze], [Silver], [Gold], [Platinum], [AnotherOne] from ( select c.name, cr.description, r.typeid from customers c left join rewards r on c.id = r.customerid left join customerrewards cr on r.typeid = cr.typeid ) x pivot ( count(typeid) for description in ([Bronze], [Silver], [Gold], [Platinum], [AnotherOne]) ) p ) x group by name with rollup 

dynamic版( Demo ):

 DECLARE @cols AS NVARCHAR(MAX), @colsRollup AS NVARCHAR(MAX), @query AS NVARCHAR(MAX) select @cols = STUFF((SELECT ',' + QUOTENAME(description) from customerrewards group by description, typeid order by typeid FOR XML PATH(''), TYPE ).value('.', 'NVARCHAR(MAX)') ,1,1,'') select @colsRollup = STUFF((SELECT ', Sum(' + QUOTENAME(description) + ') as '+ QUOTENAME(description) from customerrewards group by description, typeid order by typeid FOR XML PATH(''), TYPE ).value('.', 'NVARCHAR(MAX)') ,1,1,'') set @query = 'SELECT name, '+ @colsRollup + ' FROM ( SELECT name,' + @cols + ' from ( select c.name, cr.description, r.typeid from customers c left join rewards r on c.id = r.customerid left join customerrewards cr on r.typeid = cr.typeid ) x pivot ( count(typeid) for description in (' + @cols + ') ) p ) x1 GROUP BY name with ROLLUP' execute(@query)