棘手的聚合 Oracle 11G

Tricky aggregation Oracle 11G

我正在使用 Oracle 11G。 这是我在 table 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) 是所有 classes 的数据总和。

我想计算每个 class 与除自身以外的其他 class 相比如何。

示例: 取 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%)

我想计算每个年级的同伴集体百分比。

我该怎么做?

我不知道如何处理 "All" 记录,但对于其他人来说,这是一种方法:

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 中的示例

另一种方法可能是利用 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 记录的存在。

更新

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

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';

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