Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,购买链接:点击进入购买VIP会员
JAVA高级面试进阶视频教程Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程

Go语言视频零基础入门到精通

Java架构师3期(课件+源码)

Java开发全终端实战租房项目视频教程

SpringBoot2.X入门到高级使用教程

大数据培训第六期全套视频教程

深度学习(CNN RNN GAN)算法原理

Java亿级流量电商系统视频教程

互联网架构师视频教程

年薪50万Spark2.0从入门到精通

年薪50万!人工智能学习路线教程

年薪50万!大数据从入门到精通学习路线年薪50万!机器学习入门到精通视频教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程 MySQL入门到精通教程
查看: 274|回复: 0

[默认分类] SQL行转列汇总

[复制链接]
  • TA的每日心情
    开心
    2021-12-13 21:45
  • 签到天数: 15 天

    [LV.4]偶尔看看III

    发表于 2018-7-6 15:10:57 | 显示全部楼层 |阅读模式
    PIVOT 用于将列值旋转为列名(即行转列),在 SQL Server 2000可以用聚合函数配合CASE语句实现
    PIVOT 的一般语法是:PIVOT(聚合函数(列) FOR 列 in (…) )AS P
    注意:PIVOT、UNPIVOT是SQL Server 2005 的语法,使用需修改数据库兼容级别(在数据库属性->选项->兼容级别改为   90 )
    SQL2008 中可以直接使用


      完整语法:
      
       
       
       
       
    1. table_source
    2. PIVOT(
    3. 聚合函数(value_column)
    4. FOR pivot_column
    5. IN(<column_list>)
    6. )
    复制代码
       View Code
      
      UNPIVOT 用于将列明转为列值(即列转行),在SQL Server 2000可以用UNION来实现
      
       
       
       
       
    1. 完整语法:
    2. table_source
    3. UNPIVOT(
    4. value_column
    5. FOR pivot_column
    6. IN(<column_list>)
    7. )
    复制代码
       
       View Code
      
       
      典型实例
      一、行转列
      1、建立表格
      
      
    1. IF OBJECT_ID("tb") IS NOT NULL DROP TABLE tb
    2. go
    3. CREATE TABLE tb(姓名 VARCHAR(10),课程 VARCHAR(10),分数 INT)
    4. insert into tb VALUES ("张三","语文",74)
    5. insert into tb VALUES ("张三","数学",83)
    6. insert into tb VALUES ("张三","物理",93)
    7. insert into tb VALUES ("李四","语文",74)
    8. insert into tb VALUES ("李四","数学",84)
    9. insert into tb VALUES ("李四","物理",94)
    10. go
    11. SELECT * FROM tb
    12. go
    复制代码
      
      姓名       课程       分数
      ---------- ---------- -----------
      张三       语文        74
      张三       数学        83
      张三       物理        93
      李四       语文        74
      李四       数学        84
      李四       物理        94
       
      2、使用SQL Server 2000静态SQL
      
       
       
       
       
    1. SELECT 姓名,
    2. max(CASE 课程 WHEN"语文" THEN 分数 ELSE 0 END) 语文,
    3. max(CASE 课程 WHEN"数学" THEN 分数 ELSE 0 END) 数学,
    4. max(CASE 课程 WHEN"物理" THEN 分数 ELSE 0 END) 物理
    5. FROM tb
    6. GROUP BY 姓名
    复制代码
       
       View Code
      
      3、使用SQL Server 2000动态SQL
      
       
       
       
       
    1. --SQL SERVER 2000动态SQL,指课程不止语文、数学、物理这三门课程。(以下同)
    2. --变量按sql语言顺序赋值
    3. declare@sqlvarchar(500)
    4. set@sql="select姓名"
    5. select@sql=@sql+",max(case课程when """+课程+""" then分数else 0 end)["+课程+"]"
    6. from(selectdistinct课程fromtb)a--同from tb group by课程,默认按课程名排序
    7. set@sql=@sql+" from tb group by姓名"
    8. exec(@sql)
    9. --使用isnull(),变量先确定动态部分
    10. declare@sqlvarchar(8000)
    11. select@sql=isnull(@sql+",","")+" max(case课程when """+课程+""" then分数else 0 end) ["+课程+"]"
    12. from(selectdistinct课程fromtb)asa      
    13. set@sql="select姓名,"+@sql+" from tb group by姓名"
    14. exec(@sql)
    复制代码
       
       View Code
      
      4、使用SQL Server 2005静态SQL
      
      
    1. SELECT * FROM tb pivot( MAX(分数) FOR 课程 IN (语文,数学,物理))a
    复制代码
      
      姓名       语文        数学        物理
      ---------- ----------- ----------- -----------
      李四        74          84          94
      张三        74          83          93
      5、使用SQL Server 2005动态SQL
      
      
    1. --使用stuff()
    2. DECLARE @sql VARCHAR(8000)
    3. SET @sql=""  --初始化变量 @sql
    4. SELECT @sql= @sql+"," + 课程 FROM tb GROUP BY 课程 --变量多值赋值
    5. SET @sql= STUFF(@sql,1,1,"")--去掉首个","
    6. SET @sql="select * from tb pivot (max(分数) for 课程 in ("+@sql+"))a"
    7. PRINT @sql
    8. exec(@sql)
    9. --或使用isnull()
    10. DECLARE @sql VARCHAR(8000)
    11. --获得课程集合
    12. SELECT @sql= ISNULL(@sql+",","")+课程 FROM tb
    13. GROUP BY 课程           
    14. SET @sql="select * from tb pivot (max(分数) for 课程 in ("+@sql+"))a"
    15. exec(@sql)
    复制代码
      
      二、行转列结果加上总分、平均分
      1、使用SQL Server 2000静态SQL
      
       
       
       
       
    1. --SQL SERVER 2000静态SQL
    2. select姓名,
    3. max(case课程when"语文"then分数else0end)语文,
    4. max(case课程when"数学"then分数else0end)数学,
    5. max(case课程when"物理"then分数else0end)物理,
    6. sum(分数)总分,
    7. cast(avg(分数*1.0)asdecimal(18,2))平均分
    8. fromtb
    9. groupby姓名
    复制代码
       
       View Code
      
      姓名       语文        数学        物理        总分        平均分
      ---------- ----------- ----------- ----------- -----------
      李四        74          84          94          252         84.00
      张三        74          83          93          250         83.33
       
      2、使用SQL Server 2000动态SQL
      
       
       
       
       
    1. --SQL SERVER 2000动态SQL
    2. declare@sqlvarchar(500)
    3. set@sql="select姓名"
    4. select@sql=@sql+",max(case课程when """+课程+""" then分数else 0 end)["+课程+"]"
    5. from(selectdistinct课程fromtb)a
    6. set@sql=@sql+",sum(分数)总分,cast(avg(分数*1.0) as decimal(18,2))      平均分from tb group by姓名"
    7. exec(@sql)
    复制代码
       
       View Code
      
       
      3、使用SQL Server 2005静态SQL
      
      
    1. SELECT  m.* ,
    2.         n.总分 ,
    3.         n.平均分
    4. FROM    ( SELECT    *
    5.           FROM      tb PIVOT( MAX(分数) FOR 课程 IN ( 语文, 数学, 物理 ) ) a
    6.         ) m ,
    7.         ( SELECT    姓名 ,
    8.                     SUM(分数) 总分 ,
    9.                     CAST(AVG(分数 * 1.0) AS DECIMAL(18, 2)) 平均分
    10.           FROM      tb
    11.           GROUP BY  姓名
    12.         ) n
    13. WHERE   m.姓名 = n.姓名
    复制代码
      
      4、使用SQL Server 2005动态SQL
      
       
       
       
       
    1. --使用stuff()
    2. DECLARE @sql VARCHAR(8000)
    3. SET @sql = ""
    4.   --初始化变量@sql
    5. SELECT  @sql = @sql + "," + 课程
    6. FROM    tb
    7. GROUP BY 课程
    8. --变量多值赋值
    9. --同select @sql = @sql + ","+课程 from (select distinct 课程 from tb)a
    10. SET @sql = STUFF(@sql, 1, 1, "")
    11. --去掉首个","
    12. SET @sql = " select m.* , n.总分,n.平均分 from
    13. (select * from (select * from tb) a pivot (max(分数) for 课程 in (" + @sql
    14.     + ")) b) m ,
    15. (select 姓名,sum(分数)总分, cast(avg(分数*1.0) as decimal(18,2)) 平均分 from tb group by 姓名) n
    16. where m.姓名= n.姓名"
    17. EXEC(@sql)
    18. --或使用isnull()
    19. DECLARE @sql VARCHAR(8000)
    20. SELECT  @sql = ISNULL(@sql + ",", "") + 课程
    21. FROM    tb
    22. GROUP BY 课程
    23. SET @sql = "select m.* , n.总分,n.平均分 from
    24. (select * from (select * from tb) a pivot (max(分数) for 课程 in (" + @sql
    25.     + ")) b) m ,
    26. (select 姓名,sum(分数)总分, cast(avg(分数*1.0) as decimal(18,2)) 平均分 from tb group by 姓名) n
    27. where m.姓名= n.姓名"
    28. EXEC(@sql)
    复制代码
       
       View Code
      
       
      二、列转行
      1、建立表格
      
      
    1. IF OBJECT_ID("tb") IS NOT NULL DROP TABLE tb
    2. go
    3. CREATE TABLE tb(姓名 VARCHAR(10),语文 INT,数学 INT,物理 INT)
    4. INSERT INTO tb VALUES("张三",74,83,93)
    5. INSERT INTO tb VALUES("李四",74,84,94)
    6. go
    7. SELECT * FROM tb
    复制代码
      
      姓名       语文        数学        物理
      ---------- ----------- ----------- -----------
      张三       74          83          93
      李四        74          84          94
      2、使用SQL Server 2000静态SQL
      
       
       
       
       
    1. --SQL SERVER 2000静态SQL。
    2. select*from
    3. (
    4. select姓名,课程="语文",分数=语文fromtb
    5. unionall
    6. select姓名,课程="数学",分数=数学fromtb
    7. unionall
    8. select姓名,课程="物理",分数=物理fromtb
    9. ) t
    10. orderby姓名,case课程when"语文"then1when"数学"then2when"物理"then3end
    复制代码
       
       View Code
      
      姓名       课程 分数
      ---------- ---- -----------
      李四       语文 74
      李四       数学 84
      李四       物理 94
      张三       语文 74
      张三       数学 83
      张三       物理 93
       
      2、使用SQL Server 2000动态SQL
      
       
       
       
       
    1. --SQL SERVER 2000动态SQL。
    2. --调用系统表动态生态。
    3. declare@sqlvarchar(8000)
    4. select@sql=isnull(@sql+" union all ","")+" select姓名, [课程]="
    5. +quotename(Name,"""")+" , [分数] = "+quotename(Name)+" from tb"
    6. fromsyscolumns
    7. whereName!="姓名"andID=object_id("tb")--表名tb,不包含列名为姓名的其他列
    8. orderbycolid
    9. exec(@sql+" order by姓名")
    10. go
    复制代码
       
       View Code
      
       
      3、使用SQL Server 2005静态SQL
      
      
    1. --SQL SERVER 2005动态SQL
    2. SELECT  姓名 ,
    3.         课程 ,
    4.         分数
    5. FROM    tb UNPIVOT ( 分数 FOR 课程 IN ( [语文], [数学], [物理] ) ) t
    复制代码
      
      4、使用SQL Server 2005动态SQL
      
      
    1. --SQL SERVER 2005动态SQL
    2. DECLARE @sql NVARCHAR(4000)
    3. SELECT  @sql = ISNULL(@sql + ",", "") + QUOTENAME(name)
    4. FROM    syscolumns
    5. WHERE   id = OBJECT_ID("tb")
    6.         AND name NOT IN ( "姓名" )
    7. ORDER BY colid
    8. SET @sql = "select 姓名,[课程],[分数] from tb unpivot ([分数] for [课程] in(" + @sql
    9.     + "))b"
    10. EXEC(@sql)
    复制代码
      
       
      来自大神张志涛

    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|Java学习者论坛 ( 声明:本站资料整理自互联网,用于Java学习者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2025-2-24 04:40 , Processed in 0.378026 second(s), 46 queries .

    Powered by Discuz! X3.4

    © 2001-2017 Comsenz Inc.

    快速回复 返回顶部 返回列表