菜鸟求可选择日期段生成报表的SQL语句

flashhero 2008-03-06 06:59:02
求各位大侠,是这样的,原表A是这样的:
序号 姓名 日期
1000 甲 3月1日
1001 甲 3月1日
1002 甲 3月3日
1003 乙 3月2日
1004 丁 3月2日
1005 甲 3月4日
1006 乙 3月1日
1007 乙 3月2日
1008 甲 3月1日
1009 丁 3月1日
1010 甲 3月3日
xxxx x x月x日
======================
写一个SQL语句要求选择日期段如3月1日到3月4日的每个人的使用次数
生成报表格式如下:
姓名\日期 3月1日 3月2日 3月3日 3月4日
甲 3 0 2 1
乙 1 2 0 0
丁 1 1 0 0

...全文
74 点赞 收藏 7
写回复
7 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
flashhero 2008-03-06
不好意思,今天的分都给玩了,明天加分给后面的。如果大家还有其它的写法欢迎贴出来,本人菜鸟,能有一句可以搞定的吗?日期自己在语句里改。
回复
JiangHongTao 2008-03-06
create table os(序号 varchar(10),姓名 varchar(10),日期 varchar(10))
insert into os select '1000','甲','3月1日'
insert into os select '1001','甲','3月1日'
insert into os select '1002','甲','3月3日'
insert into os select '1003','乙','3月2日'
insert into os select '1004','丁','3月2日'
insert into os select '1005','甲','3月4日'
insert into os select '1006','乙','3月1日'
insert into os select '1007','乙','3月2日'
insert into os select '1008','甲','3月1日'
insert into os select '1009','丁','3月1日'
insert into os select '1010','甲','3月3日'

declare @s varchar(8000)
declare @b varchar(10),@e varchar(10)
select @s = '',@b = '3月1日',@e = '3月4日'

select @s = @s+',sum(case 日期 when '''+日期 +''' then 1 else 0 end) as ['+日期+']' from os
where 日期 between @b and @e group by 日期 order by 日期

select @s = 'select 姓名 as [姓名/日期]'+@s+' from os where 日期 between '''+@b+''' and +'''+@e+''' group by 姓名 '

exec(@s)
/*
姓名/日期 3月1日 3月2日 3月3日 3月4日
---------- ----------- ----------- ----------- -----------
丁 1 1 0 0
甲 3 0 2 1
乙 1 2 0 0
*/
drop table os
回复
liangCK 2008-03-06
很麻烦..不玩了..

create table tb(id char(4),name nvarchar(10),dt nvarchar(20))
insert tb select '1000', '甲' ,'3月1日'
insert tb select '1001', '甲', '3月1日'
insert tb select '1002', '甲', '3月3日'
insert tb select '1003', '乙', '3月2日'
insert tb select '1004', '丁', '3月2日'
insert tb select '1005', '甲', '3月4日'
insert tb select '1006', '乙', '3月1日'
insert tb select '1007', '乙', '3月2日'
insert tb select '1008', '甲', '3月1日'
insert tb select '1009', '丁', '3月1日'
insert tb select '1010', '甲', '3月3日'

declare @sql nvarchar(4000)
declare @dt_begin varchar(10),@dt_end varchar(10)

--在这设置起始和结束日期
set @dt_begin='3-1'
set @dt_end='3-4'

set @sql='select name'
select @sql=@sql+',sum(case when dt='''+dt+''' then 1 else 0 end) ['+dt+']'
from
(
select distinct *
from (select dt,'1900-'+replace(replace(dt,'月','-'),'日','') dat
from tb) tt
where dat between '1900-'+@dt_begin and '1900-'+@dt_end
) t

set @sql=@sql+' from (select *,''1900-''+replace(replace(dt,''月'',''-''),''日'','''') dat
from tb) ta where dat between ''1900-'+@dt_begin+''' and ''1900-'+@dt_end+''' group by name order by name'

exec (@sql)

drop table tb

/*
name 3月1日 3月2日 3月3日 3月4日
---------- ----------- ----------- ----------- -----------
丁 1 1 0 0
甲 3 0 2 1
乙 1 2 0 0

(3 行受影响)
*/
回复
pt1314917 2008-03-06

--上面应该先where.后group by 。手误。。另外日期是字符型。有点难搞噢

create table os(序号 varchar(10),姓名 varchar(10),日期 varchar(10))
insert into os select '1000','甲','3月1日'
insert into os select '1001','甲','3月1日'
insert into os select '1002','甲','3月3日'
insert into os select '1003','乙','3月2日'
insert into os select '1004','丁','3月2日'
insert into os select '1005','甲','3月4日'
insert into os select '1006','乙','3月1日'
insert into os select '1007','乙','3月2日'
insert into os select '1008','甲','3月1日'
insert into os select '1009','丁','3月1日'
insert into os select '1010','甲','3月3日'

declare @sql varchar(8000)
set @sql='select 姓名'
select @sql=@sql+',['+日期+']=sum(case 日期 when '''+日期+''' then 1 else 0 end)' from
(select distinct 日期 from os where left(日期,charindex('月',日期)-1)='3'
and cast(substring(日期,charindex('月',日期)+1,charindex('日',日期)-charindex('月',日期)-1) as int) between 1 and 4)a
set @sql=@sql+' from os where left(日期,charindex(''月'',日期)-1)=''3''
and cast(substring(日期,charindex(''月'',日期)+1,charindex(''日'',日期)-charindex(''月'',日期)-1) as int) between 1 and 4 group by 姓名 '
exec(@sql)

回复
pt1314917 2008-03-06

declare @sql varchar(8000)
set @sql='select 姓名'
select @sql=@sql+',['+日期+']=sum(case 日期 when '''+日期+''' then 1 else 0 end)' from
(select distinct 日期 from 表名 where 日期 between '3月1日' and '3月4日')a
set @sql=@sql+' from 表名 group by 姓名 where 日期 between ''3月1日'' and ''3月4日'''
exec(@sql)
回复
flashhero 2008-03-06
你好 能专门针对我的问题写个动态的吗?
回复
liangCK 2008-03-06
/*
普通行列转换
(爱新觉罗.毓华 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 end

drop table tb1


--> 2005 静态
select * from (select * from #T) a pivot (max(分数) for 课程 in (语文,数学,英语)) b

--> 2005 动态
declare @2005 nvarchar(4000)
select @2005=isnull(@2005+',','')+课程 from #T group by 课程
exec ('select * from (select * from #T) a pivot (max(分数) for 课程 in ('+@2005+')) b')
回复
相关推荐
发帖
MS-SQL Server
创建于2007-09-28

3.3w+

社区成员

MS-SQL Server相关内容讨论专区
申请成为版主
帖子事件
创建了帖子
2008-03-06 06:59
社区公告
暂无公告