2017-09-25 5 views
1

Oracle 11gを使用しています。Oracle SQL Group over Integer Range

学生IDとマークのリストを保持するテーブルが1つあります。別のルックアップテーブルは、各等級の境界値を保持する。

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 

私は、各グレードの境界にある生徒の数を返すクエリを作成しようとしています。例:

実際のデータには約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

hh?参加してください。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;