当前位置: 代码迷 >> Sql Server >> 成绩统计 100分,该如何处理
  详细解决方案

成绩统计 100分,该如何处理

热度:23   发布时间:2016-04-24 08:54:59.0
成绩统计 100分
表A:学生表 (学号关联)
表B:学生科目成绩表 ( 数字,语文,英语等)(学号关联)

统计:学生的 各单科成绩,总分,平均分,排名(按这排序)

统计的科目成绩,但不一定是全部科目,按条件查询其中一个或多个科目成绩。

如果查询两科成绩出现结果
学生/学号    语文    数字   总成绩    平均分    排名
1001            80       90         170       85            1
1008             82       80         162      81            2
.....................................

如果查询三科成绩出现结果
学生/学号    语文    数字  英语  总成绩    平均分    排名
1001            80       90      100    270        90            1
1008             82       80       81     243        81            2
.....................................


求统计语句,,谢谢。。。。。。。。。

------解决思路----------------------
给点数据及结果。
------解决思路----------------------
CREATE TABLE Student(
strCode varchar(10) NOT NULL  PRIMARY KEY,
strName varchar(50) NULL
)
CREATE TABLE Grade(
strCode varchar(10) NOT NULL, 
strCourse varchar(50)NOT NULL,
fGrade FLOAT NOT NULL  
)
ALTER TABLE Grade
ADD CONSTRAINT pk_Grade PRIMARY KEY(strCode, strCourse)

go
INSERT INTO Student(strCode,strName) VALUES ('1001 ','张三')
INSERT INTO Student(strCode,strName) VALUES ('1002 ','王五')
INSERT INTO Student(strCode,strName) VALUES ('1008 ','李四')

INSERT INTO Grade(strCode,strCourse,fGrade) VALUES ('1001 ','语文',80)
INSERT INTO Grade(strCode,strCourse,fGrade) VALUES ('1001 ','数学',90)
INSERT INTO Grade(strCode,strCourse,fGrade) VALUES ('1001 ','英语',100)
INSERT INTO Grade(strCode,strCourse,fGrade) VALUES ('1002 ','语文',65)
INSERT INTO Grade(strCode,strCourse,fGrade) VALUES ('1002 ','数学',68)
INSERT INTO Grade(strCode,strCourse,fGrade) VALUES ('1002 ','英语',77)
INSERT INTO Grade(strCode,strCourse,fGrade) VALUES ('1008 ','语文',82)
INSERT INTO Grade(strCode,strCourse,fGrade) VALUES ('1008 ','数学',80)
INSERT INTO Grade(strCode,strCourse,fGrade) VALUES ('1008 ','英语',81)
go


CREATE PROCEDURE GetGrade
@str varchar(500)
AS
declare @sqlcom nvarchar(2000)
declare @str1 varchar(500)
set @str1=''''+@str+''''
set @sqlcom='
SELECT  m.* ,
        n.总分 ,
        n.平均分, ROW_NUMBER() over(order by n.平均分 DESC ) as 排名
FROM    ( SELECT    *
          FROM      Grade PIVOT( MAX(fGrade) FOR strCourse IN ( '+@str+' ) ) a
        ) m ,
        ( SELECT    strCode ,
                    SUM(fGrade) 总分 ,
                    CAST(AVG(fGrade * 1.0) AS DECIMAL(18, 2)) 平均分
          FROM      Grade where '+@str1+' like ''%''+strCourse+''%''
          GROUP BY  strCode
        ) n
WHERE   m.strCode = n.strCode'

print @sqlcom
exec(@sqlcom)
go
exec GetGrade '语文'
exec GetGrade '语文,数学'
exec GetGrade '语文,数学,英语'

执行存储过程所得结果如下图:

------解决思路----------------------

-- 快下班了,写一个
-- 要动态 SQL 。
create table test(xh int , km varchar(10) , cj int)
go
insert into test(xh , km,cj) values
(1001 ,'语文', 80 ),
(1001 ,'数学', 90 ),
(1001 ,'英语', 100),
(1008 ,'语文' ,82 ),
(1008 ,'数学', 80 ),
(1008 ,'英语', 81 )
go
declare @sql varchar(2000) = 'select xh ,'
declare @km varchar(100)
declare @s varchar(100)
declare @condition varchar(100)
set @condition = '语文,数学,'
set @s = @condition

while charindex(',',@s,1) > 0 
begin
    set @km = substring(@s,1,charindex(',',@s,1)-1)
    set @s = substring(@s,charindex(',',@s,1) + 1 ,len(@s))
    set @sql = @sql + 'sum(case when km = ''' + @km + ''' then cj end) as ' + @km + ','
end

set @sql = @sql + 'sum(cj) as sum_cj ,' 
set @sql = @sql + 'avg(cj) as avg_cj ,' 
set @sql = @sql + 'row_number() over(order by sum(cj) desc ) as mc'
set @sql = @sql + ' from test where charindex(km,''' + @condition + ''') > 0 group by xh';

exec (@sql)

go
drop table test 
go

(6 行受影响)
xh          语文          数学          sum_cj      avg_cj      mc
----------- ----------- ----------- ----------- ----------- --------------------
1001        80          90          170         85          1
1008        82          80          162         81          2

(2 行受影响)



------解决思路----------------------
建议楼主再提问时,把数据组织好,这样可以节省那些大神们的时间。

------解决思路----------------------
用case when 效率会低很多的,建议用行转列来处理
------解决思路----------------------
因为你查询的科目不确定,是动态的,建议最好用存储过程或函数来调用。
直接用SQL语句的话,你每次都要去修改条件,不建议使用
直接用SQL语句查询语文和数学的话可以这样写
SELECT  m.* ,
        n.总分 ,
        n.平均分, ROW_NUMBER() over(order by n.平均分 DESC ) as 排名
FROM    ( SELECT    *
          FROM      Grade PIVOT( MAX(fGrade) FOR strCourse IN ( 语文,数学 ) ) a
        ) m ,
        ( SELECT    strCode ,
                    SUM(fGrade) 总分 ,
                    CAST(AVG(fGrade * 1.0) AS DECIMAL(18, 2)) 平均分
          FROM      Grade where '语文,数学' like '%'+strCourse+'%'
          GROUP BY  strCode
        ) n
WHERE   m.strCode = n.strCode

------解决思路----------------------
把一堆语句放在一个SQL 块就可以了,完全可以不用存储过程。

但是,还是建议使用存储过程,以后万一逻辑有变动,处理起来会方便很多。
  相关解决方案