将表转换为同一表的分组统计信息

时间:2014-11-06 10:18:13

标签: sql sql-server

在MS-SQL中,我有一个表hasStudied(sid,ccode,grade)(学生ID,课程代码,成绩),它跟踪学生已经学过的课程和他们获得的成绩。

作为我的查询的输出,我想返回一个课程列表,其中旁边的列中传递(=非'F')学生的百分比按照该百分比的降序排列,如下所示:

C1 : 85
C3 : 70
C2 : 67

我目前设法将它们分成两个单独的表,一个包含课程代码和通过课程的人数,一个包含课程代码和阅读课程的人数。

这是由两个相对简单的语句完成的,但是要求我在java中进行大量低效的计算。

有没有办法在单个查询中进行此操作?

2 个答案:

答案 0 :(得分:0)

假设您在同一个课程下没有同一个学生的两个条目,那么应该这样做:

SELECT
ccode,
ROUND((passed::numeric(15,2) / taken_course::numeric(15,2)) * 100, 0) AS percentage_passed
FROM(
    SELECT
    ccode,
    sum(CASE WHEN grade > 2 THEN 1 ELSE 0 END) AS passed,
    count(1) AS taken_course
    FROM
    hasStudied
    GROUP BY ccode
    ) foo
ORDER BY ccode
-- since you want to order DESC by values, instead do
-- ORDER BY percentage_passed

答案 1 :(得分:0)

我认为您正在寻找cte的用法:

create table #temp(StId int, ccode varchar(5), grade varchar(1))
insert into #temp Values (1,'A1','A'),(1,'A1','F'),(2,'A2','B'),(3,'A2','F'),(4,'A2','F'),(4,'A3','F'),(5,'A3','F')

;with cte as (
    select ccode
    from #temp
    group by ccode
)
select cte.ccode,ratioOfPass = cast(sum(case when t.grade <> 'F' then 1.0 else 0.0 end) as float) / count(*)
from cte
inner join #temp t on t.ccode = cte.ccode
group by cte.ccode

在计算时,将sumcase-when一起使用,不要忘记cast的sum的浮动。