例子很多,找找 公司名 一月出口 一月进口 二月出口 二月进口 三月出口 三月出口 A 10 50 60 70 30 30 B 100 20 30 10 70 20 C 50 10 30 100 70 40 D 180 350 120 150 80 150 E 60 150 150 230 50 70 F 80 20 60 10 40 40if object_id('pubs..tb') is not null drop table tb gocreate table tb(公司名 varchar(10),出口 int,进口 int,时间 datetime) insert into tb(公司名,出口,进口,时间) values('A',10 ,50 ,'2007-01-01') insert into tb(公司名,出口,进口,时间) values('A',60 ,70 ,'2007-02-01') insert into tb(公司名,出口,进口,时间) values('A',30 ,30 ,'2007-03-01') insert into tb(公司名,出口,进口,时间) values('B',100 ,20 ,'2007-01-01') insert into tb(公司名,出口,进口,时间) values('B',30 ,10 ,'2007-02-01') insert into tb(公司名,出口,进口,时间) values('B',70 ,20 ,'2007-03-01') insert into tb(公司名,出口,进口,时间) values('C',50 ,10 ,'2007-01-01') insert into tb(公司名,出口,进口,时间) values('C',30 ,100,'2007-02-01') insert into tb(公司名,出口,进口,时间) values('C',70 ,40 ,'2007-03-01') insert into tb(公司名,出口,进口,时间) values('D',180 ,350,'2007-01-01') insert into tb(公司名,出口,进口,时间) values('D',120 ,150,'2007-02-01') insert into tb(公司名,出口,进口,时间) values('D',80 ,150,'2007-03-01') insert into tb(公司名,出口,进口,时间) values('E',60 ,150,'2007-01-01') insert into tb(公司名,出口,进口,时间) values('E',150 ,230,'2007-02-01') insert into tb(公司名,出口,进口,时间) values('E',50 ,70 ,'2007-03-01') insert into tb(公司名,出口,进口,时间) values('F',80 ,20 ,'2007-01-01') insert into tb(公司名,出口,进口,时间) values('F',60 ,10 ,'2007-02-01') insert into tb(公司名,出口,进口,时间) values('F',40 ,40 ,'2007-03-01') godeclare @sql varchar(8000) set @sql = 'select 公司名' select @sql = @sql + ' , max(case convert(varchar(7),时间,120) when ''' + 月份 + ''' then 出口 end) [' + 月份 + '月出口' + ']' + ' , max(case convert(varchar(7),时间,120) when ''' + 月份 + ''' then 进口 end) [' + 月份 + '月进口' + ']' from (select distinct convert(varchar(7),时间,120) as 月份 from tb) as a set @sql = @sql + ' from tb group by 公司名' exec(@sql) drop table tb/* 公司名 2007-01月出口 2007-01月进口 2007-02月出口 2007-02月进口 2007-03月出口 2007-03月进口 ------ ------------- ------------- ------------- ------------- ------------- ----------- A 10 50 60 70 30 30 B 100 20 30 10 70 20 C 50 10 30 100 70 40 D 180 350 120 150 80 150 E 60 150 150 230 50 70 F 80 20 60 10 40 40 */
create table ta (AttendanceDate datetime,AttendanceResultID int,EmployeeID varchar(4)) insert ta select '2007-12-1',1,'0001' insert ta select '2007-12-2',1,'0001' insert ta select '2007-12-3',2,'0001' insert ta select '2007-12-1',1,'0002' insert ta select '2007-12-3',1,'0002' create table tb (AttendanceResultID int,AttendanceResultName varchar(10)) insert tb select 1,'出勤' insert tb select 1,'早退' insert tb select 1,'迟到' /* 最后的现实效果是: 横向:员工ID 2007-1-1 2007-1-2 2007-1-3 2007-1-4 2007-1-5 纵向:0001 出勤 早退 迟到 出勤 病假 0002 迟到 出勤 出勤 早退 公休 */godeclare @sql varchar(8000) set @sql = 'select EmployeeID' select @sql = @sql+',['+convert(varchar(10),AttendanceDate,120)+']=max(case when convert(varchar,AttendanceDate,120) = '''+convert(varchar,AttendanceDate,120)+''' then AttendanceResultName else '''' end) ' from (select distinct AttendanceDate from ta ) a exec( @sql+' from ta a left join tb b on a.AttendanceResultID = b.AttendanceResultID group by EmployeeID') drop table ta,tb /*EmployeeID 2007-12-01 2007-12-02 2007-12-03 ---------- ---------- ---------- ---------- 0001 早退 早退 0002 早退 早退警告: 聚合或其它 SET 操作消除了空值。 */
create table ta (AttendanceDate datetime,AttendanceResultID int,EmployeeID varchar(4)) insert ta select '2007-12-1',1,'0001' insert ta select '2007-12-2',1,'0001' insert ta select '2007-12-3',2,'0001' insert ta select '2007-12-4',2,'0001' insert ta select '2007-12-5',3,'0001' insert ta select '2007-12-1',1,'0002' insert ta select '2007-12-2',1,'0002' insert ta select '2007-12-3',1,'0002' insert ta select '2007-12-4',1,'0002' insert ta select '2007-12-5',1,'0002' create table tb (AttendanceResultID int,AttendanceResultName varchar(10)) insert tb select 1,'出勤' insert tb select 2,'早退' insert tb select 3,'迟到' /* 最后的现实效果是: 横向:员工ID 2007-1-1 2007-1-2 2007-1-3 2007-1-4 2007-1-5 纵向:0001 出勤 早退 迟到 出勤 病假 0002 迟到 出勤 出勤 早退 公休 */godeclare @sql varchar(8000) set @sql = 'select EmployeeID' select @sql = @sql+',['+convert(varchar(10),AttendanceDate,120)+']=max(case when convert(varchar,AttendanceDate,120) = '''+convert(varchar,AttendanceDate,120)+''' then AttendanceResultName else '''' end) ' from (select distinct AttendanceDate from ta ) a exec( @sql+' from ta a left join tb b on a.AttendanceResultID = b.AttendanceResultID group by EmployeeID') drop table ta,tb /*EmployeeID 2007-12-01 2007-12-02 2007-12-03 2007-12-04 2007-12-05 ---------- ---------- ---------- ---------- ---------- ---------- 0001 出勤 出勤 早退 早退 迟到 0002 出勤 出勤 出勤 出勤 出勤*/
没具体数据?给个例自己看吧. /* 普通行列转换(2007-11-18于海南三亚)假设有张学生成绩表(tb)如下: Name Subject Result 张三 语文 74 张三 数学 83 张三 物理 93 李四 语文 74 李四 数学 84 李四 物理 94 */------------------------------------------------------------------------- /* 想变成 姓名 语文 数学 物理 ---------- ----------- ----------- ----------- 李四 74 84 94 张三 74 83 93 */create table tb ( Name varchar(10) , Subject varchar(10) , Result int )insert into tb(Name , Subject , Result) values('张三' , '语文' , 74) insert into tb(Name , Subject , Result) values('张三' , '数学' , 83) insert into tb(Name , Subject , Result) values('张三' , '物理' , 93) insert into tb(Name , Subject , Result) values('李四' , '语文' , 74) insert into tb(Name , Subject , Result) values('李四' , '数学' , 84) insert into tb(Name , Subject , Result) values('李四' , '物理' , 94) go--静态SQL,指subject只有语文、数学、物理这三门课程。 select name 姓名, max(case subject when '语文' then result else 0 end) 语文, max(case subject when '数学' then result else 0 end) 数学, max(case subject when '物理' then result else 0 end) 物理 from tb group by name /* 姓名 语文 数学 物理 ---------- ----------- ----------- ----------- 李四 74 84 94 张三 74 83 93 */--动态SQL,指subject不止语文、数学、物理这三门课程。 declare @sql varchar(8000) set @sql = 'select Name as ' + '姓名' select @sql = @sql + ' , max(case Subject when ''' + Subject + ''' then Result else 0 end) [' + Subject + ']' from (select distinct 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 else 0 end) 语文, max(case subject when '数学' then result else 0 end) 数学, max(case subject when '物理' then result else 0 end) 物理, cast(avg(result*1.0) as decimal(18,2)) 平均分, sum(result) 总分 from tb group by name /* 姓名 语文 数学 物理 平均分 总分 ---------- ----------- ----------- ----------- -------------------- ----------- 李四 74 84 94 84.00 252 张三 74 83 93 83.33 250 */--动态SQL,指subject不止语文、数学、物理这三门课程。 declare @sql1 varchar(8000) set @sql1 = 'select Name as ' + '姓名' select @sql1 = @sql1 + ' , max(case Subject when ''' + Subject + ''' then Result else 0 end) [' + Subject + ']' from (select distinct 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 */drop table tb --------------------------------------------------------- --------------------------------------------------------- /* 如果上述两表互相换一下:即姓名 语文 数学 物理 张三 74 83 93 李四 74 84 94想变成 Name Subject Result ---------- ------- ----------- 李四 语文 74 李四 数学 84 李四 物理 94 张三 语文 74 张三 数学 83 张三 物理 93 */create table tb1 ( 姓名 varchar(10) , 语文 int , 数学 int , 物理 int )insert into tb1(姓名 , 语文 , 数学 , 物理) values('张三',74,83,93) insert into tb1(姓名 , 语文 , 数学 , 物理) values('李四',74,84,94)select * from ( select 姓名 as Name , Subject = '语文' , Result = 语文 from tb1 union all select 姓名 as Name , Subject = '数学' , Result = 数学 from tb1 union all select 姓名 as Name , Subject = '物理' , Result = 物理 from tb1 ) t order by name , case Subject when '语文' then 1 when '数学' then 2 when '物理' then 3 when '总分' then 4 end-------------------------------------------------------------------- /*加个平均分,总分 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 union all select 姓名 as Name , Subject = '数学' , Result = 数学 from tb1 union all select 姓名 as Name , Subject = '物理' , Result = 物理 from tb1 union all select 姓名 as Name , Subject = '平均分' , Result = cast((语文 + 数学 + 物理)*1.0/3 as decimal(18,2)) from tb1 union all select 姓名 as Name , Subject = '总分' , Result = 语文 + 数学 + 物理 from tb1 ) t order by name , case Subject when '语文' then 1 when '数学' then 2 when '物理' then 3 when '平均分' then 4 when '总分' then 5 enddrop table tb1
行转列的问题,可用动态查询.动态语句select 员工id, [2007-1-1]=(select ...)--取出此日期各员工的考勤状态 .......--需要多少日期就按第一句的语法动态生成 from 员工表 生成语句之后再执行
A 10 50 60 70 30 30
B 100 20 30 10 70 20
C 50 10 30 100 70 40
D 180 350 120 150 80 150
E 60 150 150 230 50 70
F 80 20 60 10 40 40if object_id('pubs..tb') is not null
drop table tb
gocreate table tb(公司名 varchar(10),出口 int,进口 int,时间 datetime)
insert into tb(公司名,出口,进口,时间) values('A',10 ,50 ,'2007-01-01')
insert into tb(公司名,出口,进口,时间) values('A',60 ,70 ,'2007-02-01')
insert into tb(公司名,出口,进口,时间) values('A',30 ,30 ,'2007-03-01')
insert into tb(公司名,出口,进口,时间) values('B',100 ,20 ,'2007-01-01')
insert into tb(公司名,出口,进口,时间) values('B',30 ,10 ,'2007-02-01')
insert into tb(公司名,出口,进口,时间) values('B',70 ,20 ,'2007-03-01')
insert into tb(公司名,出口,进口,时间) values('C',50 ,10 ,'2007-01-01')
insert into tb(公司名,出口,进口,时间) values('C',30 ,100,'2007-02-01')
insert into tb(公司名,出口,进口,时间) values('C',70 ,40 ,'2007-03-01')
insert into tb(公司名,出口,进口,时间) values('D',180 ,350,'2007-01-01')
insert into tb(公司名,出口,进口,时间) values('D',120 ,150,'2007-02-01')
insert into tb(公司名,出口,进口,时间) values('D',80 ,150,'2007-03-01')
insert into tb(公司名,出口,进口,时间) values('E',60 ,150,'2007-01-01')
insert into tb(公司名,出口,进口,时间) values('E',150 ,230,'2007-02-01')
insert into tb(公司名,出口,进口,时间) values('E',50 ,70 ,'2007-03-01')
insert into tb(公司名,出口,进口,时间) values('F',80 ,20 ,'2007-01-01')
insert into tb(公司名,出口,进口,时间) values('F',60 ,10 ,'2007-02-01')
insert into tb(公司名,出口,进口,时间) values('F',40 ,40 ,'2007-03-01')
godeclare @sql varchar(8000)
set @sql = 'select 公司名'
select @sql = @sql + ' , max(case convert(varchar(7),时间,120) when ''' + 月份 + ''' then 出口 end) [' + 月份 + '月出口' + ']'
+ ' , max(case convert(varchar(7),时间,120) when ''' + 月份 + ''' then 进口 end) [' + 月份 + '月进口' + ']'
from (select distinct convert(varchar(7),时间,120) as 月份 from tb) as a
set @sql = @sql + ' from tb group by 公司名'
exec(@sql) drop table tb/*
公司名 2007-01月出口 2007-01月进口 2007-02月出口 2007-02月进口 2007-03月出口 2007-03月进口
------ ------------- ------------- ------------- ------------- ------------- -----------
A 10 50 60 70 30 30
B 100 20 30 10 70 20
C 50 10 30 100 70 40
D 180 350 120 150 80 150
E 60 150 150 230 50 70
F 80 20 60 10 40 40
*/
insert ta select '2007-12-2',1,'0001'
insert ta select '2007-12-3',2,'0001'
insert ta select '2007-12-1',1,'0002'
insert ta select '2007-12-3',1,'0002'
create table tb (AttendanceResultID int,AttendanceResultName varchar(10))
insert tb select 1,'出勤'
insert tb select 1,'早退'
insert tb select 1,'迟到'
/*
最后的现实效果是:
横向:员工ID 2007-1-1 2007-1-2 2007-1-3 2007-1-4 2007-1-5
纵向:0001 出勤 早退 迟到 出勤 病假
0002 迟到 出勤 出勤 早退 公休
*/godeclare @sql varchar(8000)
set @sql = 'select EmployeeID'
select @sql = @sql+',['+convert(varchar(10),AttendanceDate,120)+']=max(case when convert(varchar,AttendanceDate,120) = '''+convert(varchar,AttendanceDate,120)+''' then AttendanceResultName else '''' end)
'
from (select distinct AttendanceDate from ta ) a
exec( @sql+'
from ta a left join tb b on a.AttendanceResultID = b.AttendanceResultID
group by EmployeeID')
drop table ta,tb
/*EmployeeID 2007-12-01 2007-12-02 2007-12-03
---------- ---------- ---------- ----------
0001 早退 早退
0002 早退 早退警告: 聚合或其它 SET 操作消除了空值。
*/
insert ta select '2007-12-2',1,'0001'
insert ta select '2007-12-3',2,'0001'
insert ta select '2007-12-4',2,'0001'
insert ta select '2007-12-5',3,'0001'
insert ta select '2007-12-1',1,'0002'
insert ta select '2007-12-2',1,'0002'
insert ta select '2007-12-3',1,'0002'
insert ta select '2007-12-4',1,'0002'
insert ta select '2007-12-5',1,'0002'
create table tb (AttendanceResultID int,AttendanceResultName varchar(10))
insert tb select 1,'出勤'
insert tb select 2,'早退'
insert tb select 3,'迟到'
/*
最后的现实效果是:
横向:员工ID 2007-1-1 2007-1-2 2007-1-3 2007-1-4 2007-1-5
纵向:0001 出勤 早退 迟到 出勤 病假
0002 迟到 出勤 出勤 早退 公休
*/godeclare @sql varchar(8000)
set @sql = 'select EmployeeID'
select @sql = @sql+',['+convert(varchar(10),AttendanceDate,120)+']=max(case when convert(varchar,AttendanceDate,120) = '''+convert(varchar,AttendanceDate,120)+''' then AttendanceResultName else '''' end)
'
from (select distinct AttendanceDate from ta ) a
exec( @sql+'
from ta a left join tb b on a.AttendanceResultID = b.AttendanceResultID
group by EmployeeID')
drop table ta,tb
/*EmployeeID 2007-12-01 2007-12-02 2007-12-03 2007-12-04 2007-12-05
---------- ---------- ---------- ---------- ---------- ----------
0001 出勤 出勤 早退 早退 迟到
0002 出勤 出勤 出勤 出勤 出勤*/
/*
普通行列转换(2007-11-18于海南三亚)假设有张学生成绩表(tb)如下:
Name Subject Result
张三 语文 74
张三 数学 83
张三 物理 93
李四 语文 74
李四 数学 84
李四 物理 94
*/-------------------------------------------------------------------------
/*
想变成
姓名 语文 数学 物理
---------- ----------- ----------- -----------
李四 74 84 94
张三 74 83 93
*/create table tb
(
Name varchar(10) ,
Subject varchar(10) ,
Result int
)insert into tb(Name , Subject , Result) values('张三' , '语文' , 74)
insert into tb(Name , Subject , Result) values('张三' , '数学' , 83)
insert into tb(Name , Subject , Result) values('张三' , '物理' , 93)
insert into tb(Name , Subject , Result) values('李四' , '语文' , 74)
insert into tb(Name , Subject , Result) values('李四' , '数学' , 84)
insert into tb(Name , Subject , Result) values('李四' , '物理' , 94)
go--静态SQL,指subject只有语文、数学、物理这三门课程。
select name 姓名,
max(case subject when '语文' then result else 0 end) 语文,
max(case subject when '数学' then result else 0 end) 数学,
max(case subject when '物理' then result else 0 end) 物理
from tb
group by name
/*
姓名 语文 数学 物理
---------- ----------- ----------- -----------
李四 74 84 94
张三 74 83 93
*/--动态SQL,指subject不止语文、数学、物理这三门课程。
declare @sql varchar(8000)
set @sql = 'select Name as ' + '姓名'
select @sql = @sql + ' , max(case Subject when ''' + Subject + ''' then Result else 0 end) [' + Subject + ']'
from (select distinct 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 else 0 end) 语文,
max(case subject when '数学' then result else 0 end) 数学,
max(case subject when '物理' then result else 0 end) 物理,
cast(avg(result*1.0) as decimal(18,2)) 平均分,
sum(result) 总分
from tb
group by name
/*
姓名 语文 数学 物理 平均分 总分
---------- ----------- ----------- ----------- -------------------- -----------
李四 74 84 94 84.00 252
张三 74 83 93 83.33 250
*/--动态SQL,指subject不止语文、数学、物理这三门课程。
declare @sql1 varchar(8000)
set @sql1 = 'select Name as ' + '姓名'
select @sql1 = @sql1 + ' , max(case Subject when ''' + Subject + ''' then Result else 0 end) [' + Subject + ']'
from (select distinct 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
*/drop table tb ---------------------------------------------------------
---------------------------------------------------------
/*
如果上述两表互相换一下:即姓名 语文 数学 物理
张三 74 83 93
李四 74 84 94想变成
Name Subject Result
---------- ------- -----------
李四 语文 74
李四 数学 84
李四 物理 94
张三 语文 74
张三 数学 83
张三 物理 93
*/create table tb1
(
姓名 varchar(10) ,
语文 int ,
数学 int ,
物理 int
)insert into tb1(姓名 , 语文 , 数学 , 物理) values('张三',74,83,93)
insert into tb1(姓名 , 语文 , 数学 , 物理) values('李四',74,84,94)select * from
(
select 姓名 as Name , Subject = '语文' , Result = 语文 from tb1
union all
select 姓名 as Name , Subject = '数学' , Result = 数学 from tb1
union all
select 姓名 as Name , Subject = '物理' , Result = 物理 from tb1
) t
order by name , case Subject when '语文' then 1 when '数学' then 2 when '物理' then 3 when '总分' then 4 end--------------------------------------------------------------------
/*加个平均分,总分
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
union all
select 姓名 as Name , Subject = '数学' , Result = 数学 from tb1
union all
select 姓名 as Name , Subject = '物理' , Result = 物理 from tb1
union all
select 姓名 as Name , Subject = '平均分' , Result = cast((语文 + 数学 + 物理)*1.0/3 as decimal(18,2)) from tb1
union all
select 姓名 as Name , Subject = '总分' , Result = 语文 + 数学 + 物理 from tb1
) t
order by name , case Subject when '语文' then 1 when '数学' then 2 when '物理' then 3 when '平均分' then 4 when '总分' then 5 enddrop table tb1
[2007-1-1]=(select ...)--取出此日期各员工的考勤状态
.......--需要多少日期就按第一句的语法动态生成
from 员工表
生成语句之后再执行
我用的是SQL2005
等我解决了这个问题来给大家放分。
http://blog.csdn.net/roy_88/archive/2007/02/13/1509413.aspx