棘手的聚合Oracle 11G

时间:2015-01-07 18:14:12

标签: sql oracle oracle11g

我正在使用Oracle 11G。 这是表格ClassGrades中的数据:

ID      Name    APlusCount  TotalStudents   PctAplus
0       All         44          95          46.31 
1       Grade1A     13          24          54.16
2       Grade1B     11          25          44.00
3       Grade1C     8           23          34.78
4       Grade1D     12          23          52.17

ID 0的数据(APlusCount,TotalStudents)是所有类的数据总和。

我想计算每个类与除自身之外的其他类的比较。

实施例: 取具有PctAplus = 54.16的Grade1A。

我想为Grade1B,Grade1C和Grade1D添加所有值,即

((Sum of APlusCount for Grade 1B,1C,1D)/(Sum of TotalStudents for Grade 1B,1C,1D))*100

=(31/71)*100=> 43.66%

因此,与同龄人相比,Grade1A(54.16%)的表现要好得多(43.66%)

我想计算每个年级的同龄人百分比。

我该怎么做?

2 个答案:

答案 0 :(得分:2)

另一种方法可能是利用All总计记录(评论中提到的自交联接),即

WITH g1 AS (
    SELECT apluscount, totalstudents
      FROM grades
     WHERE name = 'All'
)
SELECT g.name, 100*(g1.apluscount - g.apluscount)/(g1.totalstudents - g.totalstudents)
  FROM grades g, g1
 WHERE g.name != 'All';

但是我认为@Wernfried的解决方案更好,因为它不依赖于All记录的存在。

<强>更新

或者,可以在GROUP BY语句中使用聚合和WITH

WITH g1 AS (
    SELECT SUM(apluscount) AS apluscount, SUM(totalstudents) AS totalstudents
      FROM grades
     WHERE name != 'All'
)
SELECT g.name, 100*(g1.apluscount - g.apluscount)/(g1.totalstudents - g.totalstudents)
  FROM grades g, g1
 WHERE g.name != 'All';

希望这会有所帮助。同样,使用窗口函数的解决方案可能是最好的。

答案 1 :(得分:1)

我不知道如何处理“全部”记录,但对于其他记录,这是一种方法:

select Name, 
   100*(sum(APlusCount) over () - APlusCount) /
   (sum(TotalStudents) over () - TotalStudents) as result
from grades
where name <> 'All';

NAME        RESULT
=================================
Grade1A     43.661971830986
Grade1B     47.142857142857
Grade1C     50
Grade1D     44.444444444444

请参阅SQL Fiddle

中的示例