SQL 查询横表变竖表

 

/*
普通行列转换

假设有张学生成绩表(tb)如下:
Name Subject Result
张三 语文  74
张三 数学  83
张三 物理  93
李四 语文  74
李四 数学  84
李四 物理  94
*/

-------------------------------------------------------------------------
/*
想变成 
姓名         语文        数学        物理          
---------- ----------- ----------- ----------- 
李四         74          84          94
张三         74          83          93
*/

createtable tb
(
   Name    varchar(10) ,
   Subject varchar(10) ,
   Result  int
)

insertinto tb(Name , Subject , Result) values('张三' , '语文' , 74)
insertinto tb(Name , Subject , Result) values('张三' , '数学' , 83)
insertinto tb(Name , Subject , Result) values('张三' , '物理' , 93)
insertinto tb(Name , Subject , Result) values('李四' , '语文' , 74)
insertinto tb(Name , Subject , Result) values('李四' , '数学' , 84)
insertinto tb(Name , Subject , Result) values('李四' , '物理' , 94)
go

--静态SQL,指subject只有语文、数学、物理这三门课程。
select name 姓名,
  max(case subject when'语文'then result else0end) 语文,
  max(case subject when'数学'then result else0end) 数学,
  max(case subject when'物理'then result else0end) 物理
from tb
groupby name
/*
姓名         语文        数学        物理          
---------- ----------- ----------- ----------- 
李四         74          84          94
张三         74          83          93
*/

--动态SQL,指subject不止语文、数学、物理这三门课程。
declare@sqlvarchar(8000)
set@sql='select Name as '+'姓名'
select@sql=@sql+' , max(case Subject when '''+ Subject +''' then Result else 0 end) ['+ Subject +']'
from (selectdistinct Subject from tb) as a
set@sql=@sql+' from tb group by name'
exec(@sql) 
/*
姓名         数学        物理        语文          
---------- ----------- ----------- ----------- 
李四         84          94          74
张三         83          93          74
*/

-------------------------------------------------------------------
/*加个平均分,总分
姓名         语文        数学        物理        平均分                总分          
---------- ----------- ----------- ----------- -------------------- ----------- 
李四         74          84          94          84.00                252
张三         74          83          93          83.33                250
*/

--静态SQL,指subject只有语文、数学、物理这三门课程。
select name 姓名,
  max(case subject when'语文'then result else0end) 语文,
  max(case subject when'数学'then result else0end) 数学,
  max(case subject when'物理'then result else0end) 物理,
  cast(avg(result*1.0) asdecimal(18,2)) 平均分,
  sum(result) 总分
from tb
groupby name
/*
姓名         语文        数学        物理        平均分                总分          
---------- ----------- ----------- ----------- -------------------- ----------- 
李四         74          84          94          84.00                252
张三         74          83          93          83.33                250
*/

--动态SQL,指subject不止语文、数学、物理这三门课程。
declare@sql1varchar(8000)
set@sql1='select Name as '+'姓名'
select@sql1=@sql1+' , max(case Subject when '''+ Subject +''' then Result else 0 end) ['+ Subject +']'
from (selectdistinct Subject from tb) as a
set@sql1=@sql1+' , cast(avg(result*1.0) as decimal(18,2)) 平均分,sum(result) 总分 from tb group by name'
exec(@sql1) 
/*
姓名         数学        物理        语文        平均分                总分          
---------- ----------- ----------- ----------- -------------------- ----------- 
李四         84          94          74          84.00                252
张三         83          93          74          83.33                250
*/

droptable tb

---------------------------------------------------------
---------------------------------------------------------
/*
如果上述两表互相换一下:即

姓名 语文 数学 物理
张三 74  83  93
李四 74  84  94

想变成 
Name       Subject Result      
---------- ------- ----------- 
李四         语文      74
李四         数学      84
李四         物理      94
张三         语文      74
张三         数学      83
张三         物理      93
*/

createtable tb1
(
   姓名 varchar(10) ,
   语文 int ,
   数学 int ,
   物理 int
)

insertinto tb1(姓名 , 语文 , 数学 , 物理) values('张三',74,83,93)
insertinto tb1(姓名 , 语文 , 数学 , 物理) values('李四',74,84,94)

select*from
(
  select 姓名 as Name , Subject ='语文' , Result = 语文 from tb1 
  unionall
  select 姓名 as Name , Subject ='数学' , Result = 数学 from tb1
  unionall
  select 姓名 as Name , Subject ='物理' , Result = 物理 from tb1
) t
orderby name , case Subject when'语文'then1when'数学'then2when'物理'then3when'总分'then4end

--------------------------------------------------------------------
/*加个平均分,总分
Name       Subject     Result               
---------- -------    -------------------- 
李四         语文      74.00
李四         数学      84.00
李四         物理      94.00
李四         平均分    84.00
李四         总分      252.00
张三         语文      74.00
张三         数学      83.00
张三         物理      93.00
张三         平均分    83.33
张三         总分      250.00
*/

select*from
(
  select 姓名 as Name , Subject ='语文' , Result = 语文 from tb1 
  unionall
  select 姓名 as Name , Subject ='数学' , Result = 数学 from tb1
  unionall
  select 姓名 as Name , Subject ='物理' , Result = 物理 from tb1
  unionall
  select 姓名 as Name , Subject ='平均分' , Result =cast((语文 + 数学 + 物理)*1.0/3asdecimal(18,2)) from tb1
  unionall
  select 姓名 as Name , Subject ='总分' , Result = 语文 + 数学 + 物理 from tb1
) t
orderby name , case Subject when'语文'then1when'数学'then2when'物理'then3when'平均分'then4when'总分'then5end

droptable tb1

信息化技术交流群:290216011 公司网址:www.scxxfw.com

SQL 查询横表变竖表的更多相关文章

  1. MySQL中横表和竖表相互转换

    一  竖表转横表 1. 首先创建竖表 create table student ( id varchar(32) primary key, name varchar (50) not null, su ...

  2. SQL竖表转横表 / 横表转竖表

    竖表转横表 竖表结构: Name Course Grade 张三 语文 75 张三 数学 80 张三 英语 90 李四 语文 95 李四 数学 55 转换后横表结构: Name 语文 数学 英语 张三 ...

  3. sql查询 所有被锁定的表

    --sql查询  所有被锁定的表 select request_session_id spid,OBJECT_NAME(resource_associated_entity_id) tableName ...

  4. SQL查询数据并插入新表

    SQL查询数据并插入新表 --如果接受数据导入的表已经存在 insert into 表 select * from tablename --如果导入数据并生成表 select * into 表 fro ...

  5. 使用SQL查询所有数据库名和表名

    使用SQL查询所有数据库名和表名 MySQL中查询所有数据库名和表名 查询所有数据库 show databases; 1 1 查询指定数据库中所有表名 select table_name from i ...

  6. SQL查询某库所有的表所有的字段及字段的属性

    then d.name else null end) 表名, a.colorder 字段序号, a.name 字段名, ( then '√'else '' end) 标识, ( then '√' el ...

  7. SQl查询数据库库名,表名、表的列名

    查询数据库 select * From master.dbo.sysdatabases where name='数据库名' and status<>512   --读取库中的所有表名 (当 ...

  8. SQL 查询两个字段相同表的不同记录

    select b.NativeName from sanleiDB.dbo.Dictionary_Native b where not EXISTS (select a.NativeName from ...

  9. sql查询当前数据库的所有表名

    SELECT sys.tables.name as TableName from sys.tables

随机推荐

  1. 在C++中调用DLL中的函数

    如何在C++中调用DLL中的函数 应用程序使用DLL可以采用两种方式:一种是隐式链接,另一种是显式链接.在使用DLL之前首先要知道DLL中函数的结构信息.Visual C++6.0在VC\bin目录下 ...

  2. 1701. Ostap and Partners(并查集-关系)

    1701 又是类似食物链的这一类题 这题是找与根节点的和差关系 因为0节点是已知的 为0  那么所有的都可以转换为与0的和差关系 可以规定合并的两节点 由大的指向小的 然后再更新和差关系 有可能最后有 ...

  3. HashMap和Hashtable的区别(1)

    导读: 1 HashMap不是线程安全的 hastmap实现了map接口,是将键映射到值的对象,其中键和值都是对象,并且不能包含重复键,但可以包含重复值.HashMap允许null key和null ...

  4. poj3249

    显然是一道最短路径的题目,但是 1 ≤ n ≤ 100000, 0 ≤ m ≤ 1000000能轻松打爆dij+heap 怎么办? 挖掘题意,这是一个DAG图(有向无环图) 所以对于此类问题,我们有特 ...

  5. [NOI2005] 维修数列

    1500: [NOI2005]维修数列 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 8397  Solved: 2530 Description In ...

  6. javascript六难题

    1.下面代码的运行效果是什么?为什么? <html> <head> <meta charset="utf-8"> <title>DO ...

  7. [OFBiz]简介 一

    1.What is Apache OFBiz?http://ofbiz.apache.org/ 2.概述http://baike.baidu.com/view/638900.html?fromTagl ...

  8. e2e 自动化集成测试 架构 实例 WebStorm Node.js Mocha WebDriverIO Selenium Step by step (三) SqlServer数据库的访问

    上一篇文章“e2e 自动化集成测试 架构 京东 商品搜索 实例 WebStorm Node.js Mocha WebDriverIO Selenium Step by step 二 图片验证码的识别” ...

  9. Jquery Ajax 异步设置Table中某列的值

    可根据table中某列中的ID去改变某列的值! 只是参考,实际应用中不能这样做的,如果有很多行,频繁访问服务器,服务器是顶不住的! JS: $(document).ready(function () ...

  10. Mongodb千万级数据在python下的综合压力测试及应用探讨

    http://rfyiamcool.blog.51cto.com/1030776/1329351