최대값과 최소값을 뺀 평균
조건.
TEST12 TABLE에 다음과 같은 DATA가 있다.
STD_ID TERM CURR TEST1 TEST2 TEST3 TEST4 TEST5 UNIT
------- ----- ---------- ----- ----- ----- ----------- ----------
9701001 19991 공학개론 96 89 86 89 76 2
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
9701015 19991 공학개론 82 85 91 85 76 2
9701001 19991 일반물리학 84 89 84 83 78 2
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
9701015 19991 일반물리학 70 89 78 85 83 2
9701001 19991 일반화학 84 79 81 76 83 2
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
9701015 19991 일반화학 70 77 81 82 82 2
9701001 19991 전산학개론 59 69 74 91 78 2
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
9701015 19991 전산학개론 45 65 74 90 83 2
60 행이 선택되었습니다
문제.
1999년 1학기의 각학생별 과목별 성적이 5번의 시험을 통해
기록되어 있다.
각 학생/과목별 로 5번중 최대성적과 최소성적을 뺀 나머지 3개를
이용해 과목별 평균을 구하고 반올림한후 학점(UNIT)을 곱해 학생별
총점을 구한뒤 최종적으로 전체학점으로 나눈 학생별 평균을 구하고
석차를 구하는 SQL을 작성한다.
결과는 다음과 같다.
학번 평균 석차
------- ---------- ----------
9701001 81.75 4
9701002 82 3
9701003 80.75 9
9701004 82.5 2
9701005 80.25 11
9701006 83 1
9701007 80.5 10
9701008 81.25 7
9701009 78 15
9701010 81 8
9701011 80 12
9701012 81.75 4
9701013 79.25 14
9701014 81.5 6
9701015 80 12
15 행이 선택되었습니다
생각.
석차를 구하는 방법은 별도의 주제로 다루어지고 있다.
그 주제를 참고하면 그렇게 어려운 문제는 아닌듯하다.
5개의 성적중 최대값과 최소값을 어떻게 뺄 것인가?.
최대값과 최소값을 빼면 석차를 구하는법은 알고있다.
엿보기1.최대값과 동일한값이 있어도 그중 하나만 빼야하고
최소값과 동일한 값이 있어도 그중 하나만 빼야한다.
함수중 Greatest,Least 가 있다.
잘 이용해보자.
엿보기2.최대값과 최소값을 뺀 나머지 3개를 더해서 3으로 나눈값이
그학생의 해당학기의 해당과목 학기 점수 이다.
거기에 학점을 곱하고 다시 그학생이 수강한 전체학점을
나누면 그학생의 해당학기 총점이된다.
엿보기3.그렇게 구해진 학생의 평균을 동일한 DATASET과 JOIN을 걸어
자기보다 평균이 큰 학생의 수를 세고 더하기 1 을 하면
해당 학생의 석차다.
해법.
엿보기를 통해 해답은 다 나왔다.
직접 작성해보자.
스스로 작성해야 정말 자기것이 되지 않을까?.
단계1.해당과목의 학기 점수를 구하는 방식은 다음과 같이 하면 될것이다.
(TEST1+TEST2+TEST3+TEST4+TEST5
- LEAST(TEST1,TEST2,TEST3,TEST4,TEST5)
- GREATEST(TEST1,TEST2,TEST3,TEST4,TEST5)
)/3
단계2.최종 GROUP 지을 단위는 학생이므로 학생별로 SUM을한후
그값을 학생별로 SUM한 총 학점과 나누면 해당학생의평균이다.
SELECT STD_ID 학번,
SUM(ROUND( (TEST1+TEST2+TEST3+TEST4+TEST5
- LEAST(TEST1,TEST2,TEST3,TEST4,TEST5)
- GREATEST(TEST1,TEST2,TEST3,TEST4,TEST5)
)/3
) * UNIT
) / SUM(UNIT) AVRG
FROM TEST12
WHERE TERM = '19991'
GROUP BY
STD_ID
여기까지의 결과는 다음과 같다.
학번 AVRG
------- ----------
9701001 81.75
9701002 82
9701003 80.75
9701004 82.5
9701005 80.25
9701006 83
9701007 80.5
9701008 81.25
9701009 78
9701010 81
9701011 80
9701012 81.75
9701013 79.25
9701014 81.5
9701015 80
15 행이 선택되었습니다
단계3.이제 마지막으로 뒤에 석차만 붙여주면 된다.
엿보기에서 언급했듯이 동일 DATASET의 JOIN을 통해
자신의 점수보다 점수가 높은 사람의 수를 세고 더하기1을한다.
SELECT A.STD_ID 학번,
A.AVRG 평균,
COUNT(B.STD_ID) + 1 석차
FROM
( SELECT STD_ID,
SUM(ROUND( (TEST1+TEST2+TEST3+TEST4+TEST5
- LEAST(TEST1,TEST2,TEST3,TEST4,TEST5)
- GREATEST(TEST1,TEST2,TEST3,TEST4,TEST5)
)/3
) * UNIT
) / SUM(UNIT) AVRG
FROM TEST12
WHERE TERM = '19991'
GROUP BY
STD_ID
) A,
( SELECT STD_ID,
SUM(ROUND( (TEST1+TEST2+TEST3+TEST4+TEST5
- LEAST(TEST1,TEST2,TEST3,TEST4,TEST5)
- GREATEST(TEST1,TEST2,TEST3,TEST4,TEST5)
)/3
) * UNIT
) / SUM(UNIT) AVRG
FROM TEST12
WHERE TERM = '19991'
GROUP BY
STD_ID
) B
WHERE B.AVRG(+) > A.AVRG
GROUP BY
A.STD_ID,A.AVRG
최종적인 답이다.
IN-LINE VIEW A와 B는 동일하다.
두개의 DATASET A와 B가
WHERE B.AVRG(+) > A.AVRG
와 같은 조건으로 연결되면 DATASET A 하나의 ROW에 자신의
평균보다 높은 점수를 가지는 ROW가 연결되며,
우리는 그 숫자만을 세어 1을 더하기위해
COUNT(B.STD_ID) + 1 와 같이 해주고 석차라고 이름만
달아주면 된다.
B 에 (+) 가 달린 이유는 다 알고 있듯이 1등학생은 자신보다
성적이 좋은 사람이 없으므로 연결될 DATA가 없기 때문이다.
뒷풀이.
DATABASE 에서 제공되는 함수 외에도
자신이 만든 함수를 이용해서도 절차형 언어로 길게 풀어줘야할
많은 부분을 SQL 내로 끌어들일 수 있다.
RESPONSE TIME은 둘째 치더라도 하나의 SQL로 원하는 DATA를
읽어와야 될 경우는 많다.
많은 경우에 대비해 연습해 둔다면, 후에 자신의 응용력을 가미해
커다란 시간의 절약을 거둘 수 있으리라.
사족.
초보자,
KEYBOARD 두드리기 좋아하는사람,
PROCEDURE에 유난히 애착이 있는사람,
생각하기를 별로 좋아하지 않는 사람,
IN-LINE VIEW를 좋아하지 않는사람 등에게는 권하고 싶지 않은 방식이다.
조건.
TEST12 TABLE에 다음과 같은 DATA가 있다.
STD_ID TERM CURR TEST1 TEST2 TEST3 TEST4 TEST5 UNIT
------- ----- ---------- ----- ----- ----- ----------- ----------
9701001 19991 공학개론 96 89 86 89 76 2
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
9701015 19991 공학개론 82 85 91 85 76 2
9701001 19991 일반물리학 84 89 84 83 78 2
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
9701015 19991 일반물리학 70 89 78 85 83 2
9701001 19991 일반화학 84 79 81 76 83 2
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
9701015 19991 일반화학 70 77 81 82 82 2
9701001 19991 전산학개론 59 69 74 91 78 2
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
9701015 19991 전산학개론 45 65 74 90 83 2
60 행이 선택되었습니다
문제.
1999년 1학기의 각학생별 과목별 성적이 5번의 시험을 통해
기록되어 있다.
각 학생/과목별 로 5번중 최대성적과 최소성적을 뺀 나머지 3개를
이용해 과목별 평균을 구하고 반올림한후 학점(UNIT)을 곱해 학생별
총점을 구한뒤 최종적으로 전체학점으로 나눈 학생별 평균을 구하고
석차를 구하는 SQL을 작성한다.
결과는 다음과 같다.
학번 평균 석차
------- ---------- ----------
9701001 81.75 4
9701002 82 3
9701003 80.75 9
9701004 82.5 2
9701005 80.25 11
9701006 83 1
9701007 80.5 10
9701008 81.25 7
9701009 78 15
9701010 81 8
9701011 80 12
9701012 81.75 4
9701013 79.25 14
9701014 81.5 6
9701015 80 12
15 행이 선택되었습니다
생각.
석차를 구하는 방법은 별도의 주제로 다루어지고 있다.
그 주제를 참고하면 그렇게 어려운 문제는 아닌듯하다.
5개의 성적중 최대값과 최소값을 어떻게 뺄 것인가?.
최대값과 최소값을 빼면 석차를 구하는법은 알고있다.
엿보기1.최대값과 동일한값이 있어도 그중 하나만 빼야하고
최소값과 동일한 값이 있어도 그중 하나만 빼야한다.
함수중 Greatest,Least 가 있다.
잘 이용해보자.
엿보기2.최대값과 최소값을 뺀 나머지 3개를 더해서 3으로 나눈값이
그학생의 해당학기의 해당과목 학기 점수 이다.
거기에 학점을 곱하고 다시 그학생이 수강한 전체학점을
나누면 그학생의 해당학기 총점이된다.
엿보기3.그렇게 구해진 학생의 평균을 동일한 DATASET과 JOIN을 걸어
자기보다 평균이 큰 학생의 수를 세고 더하기 1 을 하면
해당 학생의 석차다.
해법.
엿보기를 통해 해답은 다 나왔다.
직접 작성해보자.
스스로 작성해야 정말 자기것이 되지 않을까?.
단계1.해당과목의 학기 점수를 구하는 방식은 다음과 같이 하면 될것이다.
(TEST1+TEST2+TEST3+TEST4+TEST5
- LEAST(TEST1,TEST2,TEST3,TEST4,TEST5)
- GREATEST(TEST1,TEST2,TEST3,TEST4,TEST5)
)/3
단계2.최종 GROUP 지을 단위는 학생이므로 학생별로 SUM을한후
그값을 학생별로 SUM한 총 학점과 나누면 해당학생의평균이다.
SELECT STD_ID 학번,
SUM(ROUND( (TEST1+TEST2+TEST3+TEST4+TEST5
- LEAST(TEST1,TEST2,TEST3,TEST4,TEST5)
- GREATEST(TEST1,TEST2,TEST3,TEST4,TEST5)
)/3
) * UNIT
) / SUM(UNIT) AVRG
FROM TEST12
WHERE TERM = '19991'
GROUP BY
STD_ID
여기까지의 결과는 다음과 같다.
학번 AVRG
------- ----------
9701001 81.75
9701002 82
9701003 80.75
9701004 82.5
9701005 80.25
9701006 83
9701007 80.5
9701008 81.25
9701009 78
9701010 81
9701011 80
9701012 81.75
9701013 79.25
9701014 81.5
9701015 80
15 행이 선택되었습니다
단계3.이제 마지막으로 뒤에 석차만 붙여주면 된다.
엿보기에서 언급했듯이 동일 DATASET의 JOIN을 통해
자신의 점수보다 점수가 높은 사람의 수를 세고 더하기1을한다.
SELECT A.STD_ID 학번,
A.AVRG 평균,
COUNT(B.STD_ID) + 1 석차
FROM
( SELECT STD_ID,
SUM(ROUND( (TEST1+TEST2+TEST3+TEST4+TEST5
- LEAST(TEST1,TEST2,TEST3,TEST4,TEST5)
- GREATEST(TEST1,TEST2,TEST3,TEST4,TEST5)
)/3
) * UNIT
) / SUM(UNIT) AVRG
FROM TEST12
WHERE TERM = '19991'
GROUP BY
STD_ID
) A,
( SELECT STD_ID,
SUM(ROUND( (TEST1+TEST2+TEST3+TEST4+TEST5
- LEAST(TEST1,TEST2,TEST3,TEST4,TEST5)
- GREATEST(TEST1,TEST2,TEST3,TEST4,TEST5)
)/3
) * UNIT
) / SUM(UNIT) AVRG
FROM TEST12
WHERE TERM = '19991'
GROUP BY
STD_ID
) B
WHERE B.AVRG(+) > A.AVRG
GROUP BY
A.STD_ID,A.AVRG
최종적인 답이다.
IN-LINE VIEW A와 B는 동일하다.
두개의 DATASET A와 B가
WHERE B.AVRG(+) > A.AVRG
와 같은 조건으로 연결되면 DATASET A 하나의 ROW에 자신의
평균보다 높은 점수를 가지는 ROW가 연결되며,
우리는 그 숫자만을 세어 1을 더하기위해
COUNT(B.STD_ID) + 1 와 같이 해주고 석차라고 이름만
달아주면 된다.
B 에 (+) 가 달린 이유는 다 알고 있듯이 1등학생은 자신보다
성적이 좋은 사람이 없으므로 연결될 DATA가 없기 때문이다.
뒷풀이.
DATABASE 에서 제공되는 함수 외에도
자신이 만든 함수를 이용해서도 절차형 언어로 길게 풀어줘야할
많은 부분을 SQL 내로 끌어들일 수 있다.
RESPONSE TIME은 둘째 치더라도 하나의 SQL로 원하는 DATA를
읽어와야 될 경우는 많다.
많은 경우에 대비해 연습해 둔다면, 후에 자신의 응용력을 가미해
커다란 시간의 절약을 거둘 수 있으리라.
사족.
초보자,
KEYBOARD 두드리기 좋아하는사람,
PROCEDURE에 유난히 애착이 있는사람,
생각하기를 별로 좋아하지 않는 사람,
IN-LINE VIEW를 좋아하지 않는사람 등에게는 권하고 싶지 않은 방식이다.
댓글 0
번호 | 제목 | 글쓴이 | 날짜 | 조회 수 |
---|---|---|---|---|
86 | 중복 data를 찾아 한번만 display하는 방법 | 운영자 | 2002.11.23 | 3429 |
85 | 중복 data를 찾아 모두 display 하는 방법 | 운영자 | 2002.11.23 | 3070 |
84 | oracle의 procedure에서의 여러 리턴값의 활용 예 | 운영자 | 2002.10.18 | 8302 |
83 | 특정문자까지의 왼쪽 문자열 반환 function | 운영자 | 2002.10.18 | 4044 |
82 | 중복자료 확인 및 삭제 | 운영자 | 2002.09.25 | 3260 |
81 | RECORD단위 DATA를 COLUMN단위로 | 운영자 | 2002.09.18 | 3681 |
80 | 누계 COLUMN이 없는 TABLE에 누계 값을 보자 (부등호 JOIN) | 운영자 | 2002.09.18 | 5104 |
79 | 바로이전 ROW의 값을 참조하고자 할때 | 운영자 | 2002.09.18 | 8619 |
78 | 누계 COLUMN이 없는 TABLE에 누계 값을 보자 (IN-LINE VIEW) | 운영자 | 2002.09.18 | 3123 |
77 | 자기보다 작은값중 최대값 하나만 읽어오기 | 운영자 | 2002.09.18 | 4589 |
76 | DATA COPY를 이용한 QUERY | 운영자 | 2002.09.18 | 3186 |
75 | PARAMETER값 변경에따른 유연한 GROUP BY | 운영자 | 2002.09.18 | 4127 |
74 | PAIRWISE 와 NONPAIRWISE | 운영자 | 2002.09.18 | 2697 |
73 | 동일한 값 안보여주기 | 운영자 | 2002.09.18 | 2970 |
72 | 소계/합계 함께 보기 | 운영자 | 2002.09.18 | 3134 |
71 | 석차구하기 | 운영자 | 2002.09.18 | 2960 |
70 | COLUMN을 ROW로 | 운영자 | 2002.09.18 | 6135 |
» | 최대값과 최소값을 뺀 평균 | 운영자 | 2002.09.18 | 4177 |
68 | 누계를 구하는 또한가지 방법 | 운영자 | 2002.09.18 | 3209 |
67 | 그룹 단위별 일련번호 붙이기 | 운영자 | 2002.09.18 | 5754 |