动态创建sql列
我有一桌顾客动态创建sql列,sql,sql-server,tsql,pivot,dynamic-pivot,Sql,Sql Server,Tsql,Pivot,Dynamic Pivot,我有一桌顾客 Customer ID Name 1 John 2 Lewis 3 Mary 我有另一张桌子,顾客服务 TypeID Description 1 Bronze 2 Silver 3
Customer ID Name
1 John
2 Lewis
3 Mary
我有另一张桌子,顾客服务
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表是动态的,其中许多类型都可以添加和删除。基本上,我只希望动态生成列,每个列中都有一个计数,比如
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
我说过的问题是,类型是动态的,客户是动态的,所以我需要根据系统中的类型使列是动态的
我已经在DataGridView中标记了c,因为我需要它
提前感谢您需要为此使用透视功能。如果列数已知,则可以对值进行硬编码:
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来透视:
看
如果需要包含总计列,则可以使用汇总:
动态版本:
这看起来像一个支点。我已经做了一些,但我无法从记忆中键入一个。也许数据库中的视图是通过在SQL端旋转数据创建的?如果需要在SQL中这样做,您可能需要动态透视。看,例如,但这不是一个真正干净的解决方案。如果您可以等待将数据输入C,您可以使用LINQ来完成这项工作。这些看起来确实很复杂!感谢您的评论,我将研究Pivot,但如果有人有一个简单的解决方案,请放心。您可能有一个SQL注入缺陷/可用性缺陷:=STUFFSELECT',Sum'+QUOTENAMEdescription+'as'+描述应该是:=STUFFSELECT',Sum'+QUOTENAMEdescription+'as'+QUOTENAMEdescription,否则,那是一篇很棒的帖子@是的,你是对的。我更新了我的代码。谢谢你接电话。
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)
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
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)