2017-09-25 87 views
1

使用Oracle 11g。Oracle SQL Group整数范围

我有一张表,其中包含学生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; 

回答

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;