棘手的聚合 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 函数的解决方案可能是最好的。
我正在使用 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 函数的解决方案可能是最好的。