使用SQL动态生成列
本文探讨数据挖掘领域一个常见问题:基于动态数据动态创建列。当需要以用户友好的格式呈现数据时,尤其是在每个动态生成的列中都需要值的计数时,就会出现这种挑战。
问题陈述
我们有三个表:Customers、CustomerRewards和Rewards。目标是生成一个新表,该表显示每个客户的姓名以及他们在每种奖励类型(例如,青铜、白银、黄金等)中拥有的奖励数量。但是,奖励类型是动态的,这意味着随着时间的推移,可以添加或删除新的类型。
解决方案:使用PIVOT函数
静态PIVOT:
如果事先知道奖励类型的数量,我们可以使用硬编码的PIVOT函数。例如:
<code class="language-sql">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;</code>
动态PIVOT:
如果奖励类型的数量可能会有所不同,我们可以使用动态SQL来执行PIVOT:
<code class="language-sql">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)</code>
包含总计列
要包含总计列,我们可以使用ROLLUP:
静态ROLLUP:
<code class="language-sql">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</code>
动态ROLLUP:
<code class="language-sql">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)</code>
以上是如何在SQL中动态生成带有计数的列进行数据挖掘?的详细内容。更多信息请关注PHP中文网其他相关文章!