最近在写一个销售报表的SQL,对此类型的二维SQL 进行一个总结。
表结构 Test
ProductName SaleMonth SaleNumber
A m1 1
B m1 1
A m2 2
B m2 3
要求出查询结果:
ProductName M1 M2
A 1 2
B 1 3
方法一:
创建临时表,通过游标将数据添加到临时表中。
但是此方法只适合列固定,如果列不确定,编写起来比较麻烦。所以此方法忽略。
方法二:
思路:通过Case依次创建列。
如下: (Case SaleMonth When 'M1' then SaleNumber ELSE 0 END) [M1],
(Case SaleMonth When 'M2' then SaleNumber ELSE 0 END) [M2]
带来的问题是:如何获取不确定的列名。
declare @sql varchar(8000)
SET @sql='SELECT ProductName'
-- 这步关键需要初始化,否则会无效。因为varchar类型相加,如果有个内容为空,则相加之后的内容也是为空
SELECT @sql = @sql + ',(Case SaleMonth WHEN ''' + SaleMonth
+ ''' THEN SaleNumber ELSE 0 END) ['
+ SaleMonth + ']' FROM (SELECT DISTINCT SaleMonth FROM Test) A
SET @sql = @sql + ' FROM Test'
PRINT @sql
EXEC(@sql)
运行结果如下:
p m1 m2 m3 m4
A 1 0 0 0
A 0 2 0 0
A 0 0 3 0
A 0 0 0 4
B 1 0 0 0
B 0 2 0 0
B 0 0 3 0
B 0 0 0 4
这并不是所预期的。经分析,在进行Case处理的时候加上MAX可避免。
如下:
declare @sql varchar(8000)
SET @sql='SELECT ProductName'
-- 这步关键需要初始化,否则会无效。因为varchar类型相加,如果有个内容为空,则相加之后的内容也是为空
SELECT @sql = @sql + ',MAX(Case SaleMonth WHEN ''' + SaleMonth
+ ''' THEN SaleNumber ELSE 0 END) [' + SaleMonth + ']' FROM
(SELECT DISTINCT SaleMonth FROM Test) A
SET @sql = @sql + ' FROM Test GROUP BY ProductName'
PRINT @sql
EXEC(@sql)
运行结果如下:
P M1 M2 M3 M4
A 1 2 3 4
B 1 2 3 4
效果达到预期。
但是带来了另外一个问题,如果SaleNumber中有负数的时候则会出现数据错误(此列数据会被0代替)。此时需要根据实际情况进行相应的更改。
方法三:
SQL2005中有 PIVOT函数可实现行转列
PIVOT具体介绍可以参考:http://technet.microsoft.com/zh-cn/library/ms177410.aspx
SQL如下:
SELECT * FROM (SELECT ProductName, SaleNumber, SaleMonth FROM Test) A
PIVOT(MAX(SaleNumber) FOR SaleMonth IN(m1,m2,m3,m4)) B
带来的问题是:如何动态生成M1,M2。。。
declare @sql varchar(8000)
SELECT @sql = ISNULL(@sql + ',', '') + SaleMonth FROM Test GROUP BY SaleMonth
SET @sql = 'SELECT * FROM (SELECT ProductName, SaleNumber, SaleMonth FROM Test) A
PIVOT(MAX(SaleNumber) FOR SaleMonth IN(' + @sql + ')) B'
PRINT @sql
EXEC(@sql)
总结:如果你的表中有主键或者某一列具备唯一值时,在进行创建源的时候记得将此列排除。
作者:Terry
出处:http://foolishfox.cnblogs.com/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· 展开说说关于C#中ORM框架的用法!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?