使用Oracle 11g。
我有一张表,其中包含学生ID和标记列表。另一个查找表保存每个等级的边界值。
STUDENT_MARKS:
STUDENT_ID STUDENT_MARK
1 20
2 60
3 90
4 20
GRADE_LOOKUP:
GRADE_ID GRADE LOWER_MARK UPPER_MARK
1 A 80 100
2 B 50 79
3 C 0 49
我正在尝试写一个查询来返回每个年级边界的学生数。例如:
STUDENT_GRADE STUDENT_COUNT
A 1
B 1
C 2
我编写了以下代码,它返回正确的结果,但实际数据包含大约40个“等级”边界。因此,下面的代码变得相当笨重。我理想地寻找一种方法来使用内置方法生成相同的结果,与GROUP一致。
SELECT 'A' AS STUDENT_GRADE,
COUNT(STUDENT_ID) AS STUDENT_COUNT
FROM STUDENT_MARKS
WHERE STUDENT_MARK >= (SELECT LOWER_MARK FROM GRADE_LOOKUP WHERE GRADE_ID
= 1)
UNION ALL
SELECT 'B' AS STUDENT_GRADE,
COUNT(STUDENT_ID) AS STUDENT_COUNT
FROM STUDENT_MARKS
WHERE STUDENT_MARK >= (SELECT LOWER_MARK FROM GRADE_LOOKUP WHERE GRADE_ID
= 2)
AND STUDENT_MARK <= (SELECT UPPER_MARK FROM GRADE_LOOKUP WHERE GRADE_ID
=2)
UNION ALL
SELECT 'C' AS STUDENT_GRADE,
COUNT(STUDENT_ID) AS STUDENT_COUNT
FROM STUDENT_MARKS
WHERE STUDENT_MARK <= (SELECT UPPER_MARK FROM GRADE_LOOKUP WHERE GRADE_ID
= 3);
下面的设置代码。谢谢你的帮助。
CREATE TABLE STUDENT_MARKS
(
STUDENT_ID INTEGER PRIMARY KEY,
STUDENT_MARK INTEGER
);
INSERT ALL
INTO STUDENT_MARKS (STUDENT_ID, STUDENT_MARK) VALUES (1, 20)
INTO STUDENT_MARKS (STUDENT_ID, STUDENT_MARK) VALUES (2, 60)
INTO STUDENT_MARKS (STUDENT_ID, STUDENT_MARK) VALUES (3, 90)
INTO STUDENT_MARKS (STUDENT_ID, STUDENT_MARK) VALUES (4, 20)
SELECT * FROM DUAL;
CREATE TABLE GRADE_LOOKUP
(
GRADE_ID INTEGER PRIMARY KEY,
GRADE VARCHAR2(10),
LOWER_MARK INTEGER,
UPPER_MARK INTEGER
);
INSERT ALL
INTO GRADE_LOOKUP (GRADE_ID, GRADE, LOWER_MARK, UPPER_MARK) VALUES
(1, 'A', 80, 100)
INTO GRADE_LOOKUP (GRADE_ID, GRADE, LOWER_MARK, UPPER_MARK) VALUES
(2, 'B', 50, 79)
INTO GRADE_LOOKUP (GRADE_ID, GRADE, LOWER_MARK, UPPER_MARK) VALUES
(3, 'C', 0, 49)
SELECT * FROM DUAL;
答案 0 :(得分:1)
咦?只需加入一个group by
:
SELECT gl.GRADE, COUNT(*) AS STUDENT_COUNT
FROM STUDENT_MARKS sm JOIN
GRADE_LOOKUP gl
ON sm.student_mark BETWEEN gl.LOWER_MAKR and gl.UPPER_MARK
GROUP BY gl.GRAdE
ORDER BY gl.GRADE;