SQL行转列应用的动态实现方式
SQL Server
SQL行转列的需求,在项目中还是经常可见的,尤其报表类的应用,更是非常广泛!上期我们讲了SQL行转列的静态实现方式,本期搞一下行转列的动态实现方案,解决方案并不唯一,这里采用存储过程的实现方式!

概述:

SQL行转列的需求,在项目中还是经常可见的,尤其报表类的应用,更是非常广泛!上期我们讲了SQL行转列的静态实现方式,本期搞一下行转列的动态实现方案,解决方案并不唯一,这里采用存储过程的实现方式!

 

SQL行转列应用的动态实现方式

 

接下来我们详细讲解下SQL动态行转列的实现步骤:

创建模拟数据:

这里还是老套路,IT编程人入门的经典学生选课表系列,学生表、课程表、成绩表!就拿这套耳熟能详的表结构进行讲解!

 

SQL行转列应用的动态实现方式

 

 

SQL行转列应用的动态实现方式

 

插入模拟的数据,用于动态行转案例的使用!

 

SQL行转列应用的动态实现方式

 

先写好静态行转列SQL:

这一步相对还是比较重要,毕竟我们要在一个静态的行转列基础之上,构建动态的行转列应用,课程数据会有动态变化,学生也会选择新开的课程,这样静态模式势必不会有效,但参照静态模板,去开发动态的模式,则更加有参照性!

 

  1. SELECT S.SID,S.sname,  
  2. MAX(case c.cname when '数学' then sc.score else 0 endas 数学, 
  3. MAX(case c.cname when '语文' then sc.score else 0 endas 语文, 
  4. MAX(case c.cname when '英语' then sc.score else 0 endas 英语 
  5. FROM Student as S 
  6. LEFT JOIN SC AS SC ON S.sid = SC.SID 
  7. LEFT JOIN Course AS C ON C.cid = SC.CID 
  8. GROUP BY S.sid,S.sname 

 

 

SQL行转列应用的动态实现方式

 

通过测试,数据效果没有问题,正是我们期待的样子!

编写动态脚本:

动态行转列无疑需要使用SQL编程的技术,动态的递归课程名称,这样才可以一劳永逸的解决问题!

先编写动态的SQL脚本:

 

  1. DECLARE @SQL VARCHAR(MAX
  2.  
  3. SELECT @SQL = ' SELECT S.SID,S.SNAME ' 
  4. SELECT @SQL = @SQL + ' , ISNULL(MAX(CASE c.cname WHEN '''+cname+''' THEN sc.score END ),0) AS '''+c.cname+''' '  
  5. FROM Course  AS C 
  6.  
  7. print @sql 
  8.  
  9. SELECT @SQL = @SQL + ' FROM Student as S 
  10. LEFT JOIN SC AS SC ON S.sid = SC.SID 
  11. LEFT JOIN Course AS C ON C.cid = SC.CID  
  12. GROUP BY S.sid,S.sname' 
  13.  
  14. print @sql 
  15.  
  16. EXEC (@SQL) 

 

测试结果与静态SQL完全一致,看来问题已经解决,接下来就是优化的问题了!

 

 

将上述的动态脚本封装成存储过程,第一可以尽量地提升查询效率,第二方便代码段的调用!

 

  1. CREATE PROC StudentScore_Proc 
  2. AS 
  3. BEGIN 
  4.  
  5.  
  6. DECLARE @SQL NVARCHAR(MAX
  7.  
  8. SELECT @SQL = N' SELECT S.SID,S.SNAME ' 
  9. SELECT @SQL = @SQL + N' , ISNULL(MAX(CASE c.cname WHEN '''+cname+''' THEN sc.score END ),0) AS '''+c.cname+''' '  
  10. FROM Course  AS C 
  11.  
  12.  
  13. SELECT @SQL = @SQL + N' FROM Student as S 
  14. LEFT JOIN SC AS SC ON S.sid = SC.SID 
  15. LEFT JOIN Course AS C ON C.cid = SC.CID  
  16. GROUP BY S.sid,S.sname' 
  17.  
  18. print @sql 
  19.  
  20. EXECUTE sp_executesql 
  21. @STMT = @SQL 
  22.  
  23. END 
  24.  
  25. EXEC dbo.StudentScore_Proc 

 

封装完存储过程,我们再执行一下,看看结果!果然没有任何问题,与预期完全一致!

 

 

这时候我们更改一下数据,课程表中新增物理、化学两门课程,诺克萨斯之手分别选择了两门课程,盖伦仅仅选择了化学,武器大师逃学,俩门课都没有选择。

 

  1. INSERT INTO Course SELECT 4,'物理' 
  2. INSERT INTO Course SELECT 5,'化学' 
  3.  
  4. INSERT INTO SC SELECT 1,4,99 
  5. INSERT INTO SC SELECT 1,5,88 
  6. INSERT INTO SC SELECT 2,5,77 
  7.  
  8. EXEC dbo.StudentScore_Proc 

 

数据改变之后,我们继续测试一下,再次执行我们编写好的存储过程,结果非常完美,随着数据的变化,查询的结果集也是对应的变化,非常NICE,大功告成了!

 

 

总结一下:

 

连续俩篇的文章更新,SQL行转列在项目中的应用都已经涵盖了。即将步入年底了,肯定有很多小伙伴被客户、领导追着搞各种报表,希望对小伙伴们有些许的帮助。

 

责任编辑:华轩 来源: 今日头条

编辑推荐

SQL编程之高级查询及注意事项SQL Server性能调优方法论与常用工具【SQL Server 2016动态数据屏蔽入门】Azure SQL 数据库V12版的动态数据屏蔽【SQL Server 2016动态数据屏蔽入门】定义屏蔽巧用这19条MySQL优化,效率至少提高3倍
我收藏的内容
点赞
收藏