问题:假设有张学生成绩表(tb)如下:
姓名 课程 第一次分数 第二次分数
张三 语文 74 81
张三 数学 83 93
张三 物理 93 100
李四 语文 74 89
李四 数学 84 86
李四 物理 94 96想变成(得到如下结果):
姓名 语文第一次 语文第二次 语文总分 数学第一次 数学第二次 数学总分 物理第一次 物理第二次 物理总分 总累计第一次 总累计第二次
---- ---- ---- ----
李四 74 89 163 84 .. 94 ..
张三 74 81 155 83 .. 93 ..
-------------------课程不要写死.
姓名 课程 第一次分数 第二次分数
张三 语文 74 81
张三 数学 83 93
张三 物理 93 100
李四 语文 74 89
李四 数学 84 86
李四 物理 94 96想变成(得到如下结果):
姓名 语文第一次 语文第二次 语文总分 数学第一次 数学第二次 数学总分 物理第一次 物理第二次 物理总分 总累计第一次 总累计第二次
---- ---- ---- ----
李四 74 89 163 84 .. 94 ..
张三 74 81 155 83 .. 93 ..
-------------------课程不要写死.
if object_id('[tb]') is not null drop table [tb]
go
create table [tb]([姓名] varchar(4),[课程] varchar(4),[第一次分数] int,[第二次分数] int)
insert [tb]
select '张三','语文',74,81 union all
select '张三','数学',83,93 union all
select '张三','物理',93,100 union all
select '李四','语文',74,89 union all
select '李四','数学',84,86 union all
select '李四','物理',94,96
---查询---
declare @sql varchar(8000)
select
@sql=isnull(@sql+',','')
+'max(case when 课程='''+课程+''' then 第一次分数 else 0 end) as ['+课程+'第一次分数],'
+'max(case when 课程='''+课程+''' then 第二次分数 else 0 end) as ['+课程+'第二次分数],'
+'max(case when 课程='''+课程+''' then 第一次分数+第二次分数 else 0 end) as ['+课程+'总分]'
from
(select distinct 课程 from tb) texec ('select 姓名,'+@sql+' from tb group by 姓名')
---结果---
姓名 数学第一次分数 数学第二次分数 数学总分 物理第一次分数 物理第二次分数 物理总分 语文第一次分数 语文第二次分数 语文总分
---- ----------- ----------- ----------- ----------- ----------- ----------- ----------- ----------- -----------
李四 84 86 170 94 96 190 74 89 163
张三 83 93 176 93 100 193 74 81 155(2 行受影响)
如
student subject grade
--------- ---------- --------
student1 语文 80
student1 数学 70
student1 英语 60
student2 语文 90
student2 数学 80
student2 英语 100
……
转换为
语文 数学 英语
student1 80 70 60
student2 90 80 100
……
语句如下:select student,
sum(decode(subject,'语文', grade,null)) "语文",
sum(decode(subject,'数学', grade,null)) "数学",
sum(decode(subject,'英语', grade,null)) "英语"
from table
group by student;
---查询---
declare @sql varchar(8000)
select
@sql=isnull(@sql+',','')
+'max(case when 课程='''+课程+''' then 第一次分数 else 0 end) as ['+课程+'第一次分数],'
+'max(case when 课程='''+课程+''' then 第二次分数 else 0 end) as ['+课程+'第二次分数],'
+'max(case when 课程='''+课程+''' then 第一次分数+第二次分数 else 0 end) as ['+课程+'总分]'
from
(select distinct 课程 from tb) texec (
'select 姓名,'
+@sql
+',sum(第一次分数) as [总累计第一次],sum(第二次分数) as [总累计第二次]'
+'from tb group by 姓名'
)
---结果---
姓名 数学第一次分数 数学第二次分数 数学总分 物理第一次分数 物理第二次分数 物理总分 语文第一次分数 语文第二次分数 语文总分 总累计第一次 总累计第二次
---- ----------- ----------- ----------- ----------- ----------- ----------- ----------- ----------- ----------- ----------- -----------
李四 84 86 170 94 96 190 74 89 163 252 271
张三 83 93 176 93 100 193 74 81 155 250 274(2 行受影响)
IF OBJECT_ID('[tb]') IS NOT NULL DROP TABLE [tb]
GO
create table tb(姓名 varchar(10) , 课程 varchar(10) , 分数 int)
insert into tb values('张三' , '语文' , 74)
insert into tb values('张三' , '数学' , 83)
insert into tb values('张三' , '物理' , 93)
insert into tb values('李四' , '语文' , 74)
insert into tb values('李四' , '数学' , 84)
insert into tb values('李四' , '物理' , 94)
go--select * from tb;select 姓名,[语文] as [语文],[数学] as [数学],[物理] as [物理] from tb
pivot (max(分数) for 课程 in ([语文],[数学],[物理])) pvt
-- Author :fredrickhu(小F,向高手学习)
-- Date :2011-05-10 16:44:19
-- Verstion:
-- Microsoft SQL Server 2008 (RTM) - 10.0.1600.22 (Intel X86)
-- Jul 9 2008 14:43:34
-- Copyright (c) 1988-2008 Microsoft Corporation
-- Enterprise Evaluation Edition on Windows NT 5.1 <X86> (Build 2600: Service Pack 3)
--
----------------------------------------------------------------
--> 测试数据:[tb]
if object_id('[tb]') is not null drop table [tb]
go
create table [tb]([姓名] varchar(4),[课程] varchar(4),[第一次分数] int,[第二次分数] int)
insert [tb]
select '张三','语文',74,81 union all
select '张三','数学',83,93 union all
select '张三','物理',93,100 union all
select '李四','语文',74,89 union all
select '李四','数学',84,86 union all
select '李四','物理',94,96
--------------开始查询--------------------------select
姓名,
max(case when 课程='数学' then 第一次分数 else 0 end) as [数学第一次分数],
max(case when 课程='数学' then 第二次分数 else 0 end) as [数学第二次分数],
max(case when 课程='数学' then 第一次分数+第二次分数 else 0 end) as [数学总分],
max(case when 课程='物理' then 第一次分数 else 0 end) as [物理第一次分数],
max(case when 课程='物理' then 第二次分数 else 0 end) as [物理第二次分数],
max(case when 课程='物理' then 第一次分数+第二次分数 else 0 end) as [物理总分],
max(case when 课程='语文' then 第一次分数 else 0 end) as [语文第一次分数],
max(case when 课程='语文' then 第二次分数 else 0 end) as [语文第二次分数],
max(case when 课程='语文' then 第一次分数+第二次分数 else 0 end) as [语文总分],
sum(第一次分数) as [总累计第一次],sum(第二次分数) as [总累计第二次]
from
tb
group by
姓名----------------结果----------------------------
/* 姓名 数学第一次分数 数学第二次分数 数学总分 物理第一次分数 物理第二次分数 物理总分 语文第一次分数 语文第二次分数 语文总分 总累计第一次 总累计第二次
---- ----------- ----------- ----------- ----------- ----------- ----------- ----------- ----------- ----------- ----------- -----------
李四 84 86 170 94 96 190 74 89 163 252 271
张三 83 93 176 93 100 193 74 81 155 250 274(2 行受影响)
*/
-- Author :fredrickhu(小F,向高手学习)
-- Date :2011-05-10 16:44:19
-- Verstion:
-- Microsoft SQL Server 2008 (RTM) - 10.0.1600.22 (Intel X86)
-- Jul 9 2008 14:43:34
-- Copyright (c) 1988-2008 Microsoft Corporation
-- Enterprise Evaluation Edition on Windows NT 5.1 <X86> (Build 2600: Service Pack 3)
--
----------------------------------------------------------------
--> 测试数据:[tb]
if object_id('[tb]') is not null drop table [tb]
go
create table [tb]([姓名] varchar(4),[课程] varchar(4),[第一次分数] int,[第二次分数] int)
insert [tb]
select '张三','语文',74,81 union all
select '张三','数学',83,93 union all
select '张三','物理',93,100 union all
select '李四','语文',74,89 union all
select '李四','数学',84,86 union all
select '李四','物理',94,96
--------------开始查询--------------------------declare @sql varchar(8000)
select
@sql=isnull(@sql+',','')
+'max(case when 课程='''+课程+''' then 第一次分数 else 0 end) as ['+课程+'第一次分数],'
+'max(case when 课程='''+课程+''' then 第二次分数 else 0 end) as ['+课程+'第二次分数],'
+'max(case when 课程='''+课程+''' then 第一次分数+第二次分数 else 0 end) as ['+课程+'总分]'
from
(select distinct 课程 from tb) texec ('select 姓名,'+@sql+',sum(第一次分数) as [总累计第一次],sum(第二次分数) as [总累计第二次]'+'from tb group by 姓名')
----------------结果----------------------------
/* 姓名 数学第一次分数 数学第二次分数 数学总分 物理第一次分数 物理第二次分数 物理总分 语文第一次分数 语文第二次分数 语文总分 总累计第一次 总累计第二次
---- ----------- ----------- ----------- ----------- ----------- ----------- ----------- ----------- ----------- ----------- -----------
李四 84 86 170 94 96 190 74 89 163 252 271
张三 83 93 176 93 100 193 74 81 155 250 274(2 行受影响)
*/
比如说:需求是为了将统计结果在页面上显示,这样完全可以把“行列互换”的事交给.net或者java等语言在客户端完全(借助使用arraylist等方法),效率上也许会更好一些
另外,如果使用报表工具,就需要根据情况定了,有些报告工具,功能很单一,也许只能用SQL的方法在DB server上先完成结果处理了