create table (id int,bj nvarchar(6),zf float)
insert table values select 1,'1',701
union
select 2,'2',702
union
select 3,'1',681
union
select 4,'2',501
union
select 5,'1',401
union
select 6,'1',101
分数段 计1 累1 计2 累2 总计 总累
700 1 1
690 0 1
680 1 2
. . .
. . .
300 0
其余 1
举例说明:
红色1表示1班在680<=zf<690范围有1名学生
绿色2表示1班在680<=zf范围有2名学生
“计”只是本段人数,“累”是由本段向上,不封顶,“其余”段0<zf<300,总计=计1+计2+..计n
有n个班就从计1到计n,“累”也是同理
因为班数不定,希望做成能修改的动态SQL,
insert table values select 1,'1',701
union
select 2,'2',702
union
select 3,'1',681
union
select 4,'2',501
union
select 5,'1',401
union
select 6,'1',101
分数段 计1 累1 计2 累2 总计 总累
700 1 1
690 0 1
680 1 2
. . .
. . .
300 0
其余 1
举例说明:
红色1表示1班在680<=zf<690范围有1名学生
绿色2表示1班在680<=zf范围有2名学生
“计”只是本段人数,“累”是由本段向上,不封顶,“其余”段0<zf<300,总计=计1+计2+..计n
有n个班就从计1到计n,“累”也是同理
因为班数不定,希望做成能修改的动态SQL,
解决方案 »
- 讨论下SQL的写法,有必要把所有的东西写在一条语句中吗?
- SQL逻辑查询处理顺序你不知道的二三事
- master数据库中那么多无文档的系统存储过程是干吗用的?
- 求救!!在ms sql server中输入600个字符,就被截断。为什么???
- SQL2005 Reporting Service 报表订阅问题
- 存储过程,取出一个表的数据。另外一个查询语句频繁去匹配前一个表的id找其他值
- 多条件组合查询优化(比较头痛.......)
- 请教存储过程
- 到哪里去找sql sever2000呀?大侠们指点指点。万分着急!!!
- ***关于字符串查询语句***
- 求tsql语句:按班级分组查询出语数外三科平均成绩(分数为0的不作为分母的一部分)
- 代码中的存储过程与数据库中的存储过程的区别
LZ好像上次发过这个SQL.
if object_id('tb') is not null
drop table tb
gocreate table tb([编号] int,[班级] nvarchar(10),[成绩] float)
insert tb
select 1,'高三班',701 union
select 2,'高三班',702 union
select 3,'高三班',675 union
select 4,'高三班',501 union
select 5,'高三班',401 union
select 6,'高三班',459 union
select 1,'高三班',700 union
select 2,'高三班',690 union
select 3,'高三班',681 union
select 4,'高三班',671 union
select 5,'高三班',450 union
select 6,'高三班',509IF OBJECT_ID('f_fsd', N'FN') IS NOT NULL
DROP FUNCTION f_fsd
gocreate function f_fsd(@a int)
returns int
as
begin
return ((@a/10)*10)
end
godeclare @s nvarchar(4000)
set @s=''
;with t as
(
select dbo.f_fsd([成绩]) as [分数段],[班级], count(*) as [人数]
from tb
group by dbo.f_fsd([成绩]),[班级]
)
select @s=@s+',['+班级+'人数]=sum(case when [班级]='+quotename([班级],'''')+' then [人数] else 0 end),'+
'['+班级+'人数累计]=isnull((select sum([人数]) from t where [分数段]>=t1.[分数段] and [班级]='+
quotename([班级],'''')+'),0)'
from t t1 group by [班级]
exec(
'with t as'+
'('+
' select dbo.f_fsd([成绩]) as [分数段],[班级], count(*) as [人数]'+
' from tb'+
' group by dbo.f_fsd([成绩]),[班级]'+
') '+
' select [分数段]'+@s+
' ,[总计]=(select sum([人数]) from t where [分数段]=t1.[分数段])'+
' ,[总累计]=(select sum([人数]) from t where [分数段]>=t1.[分数段])'+
' from t t1 group by [分数段],[班级] order by [分数段] desc')drop table tb
drop function f_fsd
/*
分数段 高三1班人数 高三1班人数累计 高三2班人数 高三2班人数累计 总计 总累计
700 3 3 0 0 3 3
690 1 4 0 0 1 4
680 1 5 0 0 1 5
670 0 5 2 2 2 7
500 2 7 0 2 2 9
450 0 7 2 4 2 11
400 0 7 1 5 1 12
*/
if object_id('tb') is not null
drop table tb
gocreate table tb([编号] int,[班级] nvarchar(10),[成绩] float)
insert tb
select 1,'高三1班',701 union
select 2,'高三1班',702 union
select 3,'高三2班',675 union
select 4,'高三2班',501 union
select 5,'高三2班',401 union
select 6,'高三1班',459 union
select 1,'高三2班',700 union
select 2,'高三1班',690 union
select 3,'高三1班',681 union
select 4,'高三1班',671 union
select 5,'高三2班',450 union
select 6,'高三1班',509IF OBJECT_ID('f_fsd', N'FN') IS NOT NULL
DROP FUNCTION f_fsd
gocreate function f_fsd(@a int)
returns int
as
begin
return ((@a/10)*10)
end
godeclare @s nvarchar(4000)
set @s=''
;with t as
(
select dbo.f_fsd([成绩]) as [分数段],[班级], count(*) as [人数]
from tb
group by dbo.f_fsd([成绩]),[班级]
union select 700,'dump',0
union select 690,'dump',0
union select 680,'dump',0
union select 670,'dump',0
union select 660,'dump',0
union select 650,'dump',0
union select 640,'dump',0
union select 630,'dump',0
union select 620,'dump',0
union select 610,'dump',0
union select 600,'dump',0
union select 590,'dump',0
union select 580,'dump',0
union select 570,'dump',0
union select 560,'dump',0
union select 550,'dump',0
union select 540,'dump',0
union select 530,'dump',0
union select 520,'dump',0
union select 510,'dump',0
union select 500,'dump',0
union select 490,'dump',0
union select 480,'dump',0
union select 470,'dump',0
union select 460,'dump',0
union select 450,'dump',0
union select 440,'dump',0
union select 430,'dump',0
union select 420,'dump',0
union select 410,'dump',0
union select 400,'dump',0
)
select @s=@s+',['+班级+'人数]=sum(case when [班级]='+quotename([班级],'''')+' then [人数] else 0 end),'+
'['+班级+'人数累计]=isnull((select sum([人数]) from t where [分数段]>=t1.[分数段] and [班级]='+
quotename([班级],'''')+'),0)'
from t
where [班级]<>'dump'
group by [班级]print @s
exec(
'with t as'+
'('+
' select dbo.f_fsd([成绩]) as [分数段],[班级], count(*) as [人数]'+
' from tb'+
' group by dbo.f_fsd([成绩]),[班级]'+
' union select 700,''dump'',0'+
' union select 690,''dump'',0'+
' union select 680,''dump'',0'+
' union select 670,''dump'',0'+
' union select 660,''dump'',0'+
' union select 650,''dump'',0'+
' union select 640,''dump'',0'+
' union select 630,''dump'',0'+
' union select 620,''dump'',0'+
' union select 610,''dump'',0'+
' union select 600,''dump'',0'+
' union select 590,''dump'',0'+
' union select 580,''dump'',0'+
' union select 570,''dump'',0'+
' union select 560,''dump'',0'+
' union select 550,''dump'',0'+
' union select 540,''dump'',0'+
' union select 530,''dump'',0'+
' union select 520,''dump'',0'+
' union select 510,''dump'',0'+
' union select 500,''dump'',0'+
' union select 490,''dump'',0'+
' union select 480,''dump'',0'+
' union select 470,''dump'',0'+
' union select 460,''dump'',0'+
' union select 450,''dump'',0'+
' union select 440,''dump'',0'+
' union select 430,''dump'',0'+
' union select 420,''dump'',0'+
' union select 410,''dump'',0'+
' union select 400,''dump'',0'+
') '+
' select [分数段]'+@s+
' ,[总计]=(select sum([人数]) from t where [分数段]=t1.[分数段])'+
' ,[总累计]=(select sum([人数]) from t where [分数段]>=t1.[分数段])'+
' from t t1 group by [分数段] order by [分数段] desc')drop table tb
drop function f_fsd
if object_id('tb') is not null
drop table tb
gocreate table tb([编号] int,[班级] nvarchar(10),[成绩] float)
insert tb
select 1,'高三1班',701 union
select 2,'高三1班',702 union
select 3,'高三2班',675 union
select 4,'高三2班',501 union
select 5,'高三2班',401 union
select 6,'高三1班',459 union
select 1,'高三2班',700 union
select 2,'高三1班',690 union
select 3,'高三1班',681 union
select 4,'高三1班',671 union
select 5,'高三2班',450 union
select 6,'高三1班',509IF OBJECT_ID('f_fsd', N'FN') IS NOT NULL
DROP FUNCTION f_fsd
gocreate function f_fsd(@a int)
returns int
as
begin
return ((@a/10)*10)
end
godeclare @s nvarchar(4000)
set @s=''
;with t as
(
select dbo.f_fsd([成绩]) as [分数段],[班级], count(*) as [人数]
from tb
group by dbo.f_fsd([成绩]),[班级]
)
select @s=@s+',['+班级+'人数]=sum(case when [班级]='+quotename([班级],'''')+' then [人数] else 0 end),'+
'['+班级+'人数累计]=isnull((select sum([人数]) from t where [分数段]>=t1.[分数段] and [班级]='+
quotename([班级],'''')+'),0)'
from t group by [班级]exec(
'with t as'+
'('+
' select dbo.f_fsd([成绩]) as [分数段],[班级], count(*) as [人数]'+
' from tb'+
' group by dbo.f_fsd([成绩]),[班级]'+
' union select 700,''dump'',0'+
' union select 690,''dump'',0'+
' union select 680,''dump'',0'+
' union select 670,''dump'',0'+
' union select 660,''dump'',0'+
' union select 650,''dump'',0'+
' union select 640,''dump'',0'+
' union select 630,''dump'',0'+
' union select 620,''dump'',0'+
' union select 610,''dump'',0'+
' union select 600,''dump'',0'+
' union select 590,''dump'',0'+
' union select 580,''dump'',0'+
' union select 570,''dump'',0'+
' union select 560,''dump'',0'+
' union select 550,''dump'',0'+
' union select 540,''dump'',0'+
' union select 530,''dump'',0'+
' union select 520,''dump'',0'+
' union select 510,''dump'',0'+
' union select 500,''dump'',0'+
' union select 490,''dump'',0'+
' union select 480,''dump'',0'+
' union select 470,''dump'',0'+
' union select 460,''dump'',0'+
' union select 450,''dump'',0'+
' union select 440,''dump'',0'+
' union select 430,''dump'',0'+
' union select 420,''dump'',0'+
' union select 410,''dump'',0'+
' union select 400,''dump'',0'+
') '+
' select [分数段]'+@s+
' ,[总计]=(select sum([人数]) from t where [分数段]=t1.[分数段])'+
' ,[总累计]=(select sum([人数]) from t where [分数段]>=t1.[分数段])'+
' from t t1 group by [分数段] order by [分数段] desc')--drop table tb
--drop function f_fsd
不知能不能把建立sql串的代码用循环简化一下。
if object_id('tb') is not null
drop table tb
gocreate table tb([编号] int,[班级] nvarchar(10),[成绩] float)
insert tb
select 1,'高三1班',701 union
select 2,'高三1班',702 union
select 3,'高三2班',675 union
select 4,'高三2班',501 union
select 5,'高三2班',401 union
select 6,'高三1班',459 union
select 1,'高三2班',700 union
select 2,'高三1班',690 union
select 3,'高三1班',681 union
select 4,'高三1班',671 union
select 5,'高三2班',450 union
select 6,'高三1班',509IF OBJECT_ID('f_fsd', N'FN') IS NOT NULL
DROP FUNCTION f_fsd
gocreate function f_fsd(@a int)
returns int
as
begin
return ((@a/10)*10)
end
godeclare @s nvarchar(4000)
set @s=''
;with t as
(
select dbo.f_fsd([成绩]) as [分数段],[班级], count(*) as [人数]
from tb
group by dbo.f_fsd([成绩]),[班级]
)
select @s=@s+',['+班级+'人数]=sum(case when [班级]='+quotename([班级],'''')+' then [人数] else 0 end),'+
'['+班级+'人数累计]=isnull((select sum([人数]) from t where [分数段]>=t1.[分数段] and [班级]='+
quotename([班级],'''')+'),0)'
from t group by [班级]declare @i int
declare @s2 varchar(1000)
set @s2=''
set @i=700
while @i>390
begin
set @s2=@s2+' union select '+convert(char(3),@i)+',''dump'',0'
set @i=@i-10
end;exec(
'with t as'+
'('+
' select dbo.f_fsd([成绩]) as [分数段],[班级], count(*) as [人数]'+
' from tb'+
' group by dbo.f_fsd([成绩]),[班级]'+
@s2+
') '+
' select [分数段]'+@s+
' ,[总计]=(select sum([人数]) from t where [分数段]=t1.[分数段])'+
' ,[总累计]=(select sum([人数]) from t where [分数段]>=t1.[分数段])'+
' from t t1 group by [分数段] order by [分数段] desc')--drop table tb
--drop function f_fsd
已经很接近了
各个段都正确计算了,只是“其余”段没有,“其余”的定义:0<成绩<300的人数归入“其余”段(不含0或300)
水晶没有用过,不过润乾,华单和reporting service都是可以实现的
横向扩展就是,group by 班级,分数段
然后填表格的时候,在行上填一个ds.group (班级),列上填ds.group(分数段)这样就可以实现你上面的功能了,前面两个函数是润乾报表里面的函数另外,对于可以对单元格计算的报表工具,直接像 excel那样对单元格写表达式会更加简单。
if object_id('tb') is not null
drop table tb
gocreate table tb([编号] int,[班级] nvarchar(10),[成绩] float)
insert tb
select 1,'高三1班',701 union
select 2,'高三1班',702 union
select 3,'高三2班',675 union
select 4,'高三2班',501 union
select 5,'高三2班',401 union
select 6,'高三1班',459 union
select 1,'高三2班',700 union
select 2,'高三1班',690 union
select 3,'高三1班',681 union
select 4,'高三1班',671 union
select 5,'高三2班',450 union
select 6,'高三1班',209IF OBJECT_ID('f_fsd', N'FN') IS NOT NULL
DROP FUNCTION f_fsd
gocreate function f_fsd(@a int)
returns varchar(4)
as
begin
declare @s varchar(4)
if (@a>0) and (@a <300)
set @s='其余'
else
set @s=convert(varchar(3),((@a/10)*10))
return @s
end
godeclare @s nvarchar(4000)
set @s=''
;with t as
(
select dbo.f_fsd([成绩]) as [分数段],[班级], count(*) as [人数]
from tb
group by dbo.f_fsd([成绩]),[班级]
)
select @s=@s+',['+班级+'人数]=sum(case when [班级]='+quotename([班级],'''')+' then [人数] else 0 end),'+
'['+班级+'人数累计]=isnull((select sum([人数]) from t where [分数段]>=t1.[分数段] and [班级]='+
quotename([班级],'''')+'),0)'
from t group by [班级]declare @i int
declare @s2 varchar(1200)
set @s2=''
set @i=700
while @i>290
begin
set @s2=@s2+' union select '''+convert(char(3),@i)+''',''dump'',0'
set @i=@i-10
end;
set @s2=@s2+' union select ''其余'',''dump'',0'exec(
'with t as'+
'('+
' select dbo.f_fsd([成绩]) as [分数段],[班级], count(*) as [人数]'+
' from tb'+
' group by dbo.f_fsd([成绩]),[班级]'+
@s2+
') '+
' select [分数段]'+@s+
' ,[总计]=(select sum([人数]) from t where [分数段]=t1.[分数段])'+
' ,[总累计]='+
' case when [分数段]=''其余'' then (select sum([人数]) from t) else '+
'(select sum([人数]) from t where [分数段]>=t1.[分数段] and [分数段]<>''其余'') end'+
' from t t1 group by [分数段]'+
' order by (case when [分数段]=''其余'' then 1 else 0 end), [分数段] desc')--drop table tb
--drop function f_fsd
不完整:
declare @sql nvarchar(4000)
select @sql= 'select 分数段=(cast(zf/10 as int)*10+10)'
select @sql=@sql+','+quotename('计'+bj)+'=sum(case when bj='+quotename(bj,'''')+ ' then 1 else 0 end)' from (select distinct bj from class)A
select @sql=@sql+','+quotename('累'+bj)+'=(select count(1) from class B where bj=class.bj and id<=class.id and bj='+quotename(bj,'''')+')' from (select distinct bj from class)C
set @sql=@sql+',count(*) 总计 from class group by zf,bj,id order by id'
print @sql
exec (@sql)
分数段 计1 计2 累1 累2 总计
----------- ----------- ----------- ----------- ----------- -----------
710 1 0 1 0 1
710 0 1 0 1 1
690 1 0 2 0 1
510 0 1 0 2 1
410 1 0 3 0 1
110 1 0 4 0 1
710 1 0 5 0 1
610 1 0 6 0 1
drop table tb
gocreate table tb([编号] int,[班级] nvarchar(10),[成绩] float)
insert tb
select 1,'高三1班',701 union
select 2,'高三1班',702 union
select 3,'高三2班',675 union
select 4,'高三2班',501 union
select 5,'高三2班',401 union
select 6,'高三1班',459 union
select 1,'高三2班',700 union
select 2,'高三1班',690 union
select 3,'高三1班',681 union
select 4,'高三1班',671 union
select 5,'高三2班',450 union
select 6,'高三1班',209IF OBJECT_ID('f_fsd', N'FN') IS NOT NULL
DROP FUNCTION f_fsd
gocreate function f_fsd(@a int)
returns varchar(4)
as
begin
declare @s varchar(4)
if (@a>0) and (@a <300)
set @s='其余'
else
set @s=convert(varchar(3),((@a/10)*10))
return @s
end
godeclare @s nvarchar(4000)
set @s=''
;with t as
(
select dbo.f_fsd([成绩]) as [分数段],[班级], count(*) as [人数]
from tb
group by dbo.f_fsd([成绩]),[班级]
)
select @s=@s+',['+班级+'人数]=sum(case when [班级]='+quotename([班级],'''')+' then [人数] else 0 end),'+
'['+班级+'人数累计]=isnull((select sum([人数]) from t'+
' where (([分数段]>=t1.[分数段] and [分数段]<>''其余'')or(t1.[分数段]=''其余''))'+
' and [班级]='+
quotename([班级],'''')+'),0)'
from t group by [班级]declare @i int
declare @s2 varchar(1200)
set @s2=''
set @i=700
while @i>290
begin
set @s2=@s2+' union select '''+convert(char(3),@i)+''',''dump'',0'
set @i=@i-10
end;
set @s2=@s2+' union select ''其余'',''dump'',0'exec(
'with t as'+
'('+
' select dbo.f_fsd([成绩]) as [分数段],[班级], count(*) as [人数]'+
' from tb'+
' group by dbo.f_fsd([成绩]),[班级]'+
@s2+
') '+
' select [分数段]'+@s+
' ,[总计]=(select sum([人数]) from t where [分数段]=t1.[分数段])'+
' ,[总累计]='+
' case when [分数段]=''其余'' then (select sum([人数]) from t) else '+
'(select sum([人数]) from t where [分数段]>=t1.[分数段] and [分数段]<>''其余'') end'+
' from t t1 group by [分数段]'+
' order by (case when [分数段]=''其余'' then 1 else 0 end), [分数段] desc')--drop table tb
--drop function f_fsd
我原来经常去大富翁论坛,近来转到 CSDN。大富翁论坛有一个订阅邮件功能,可以及时收到要回复的邮件。CSDN 不知道有没有订阅邮件功能?否则总是不能及时回复问题。