이번에 배울 개념은 Basic Join 과 Advanced Select입니다.
1. Basic Join & Advanced Select
2. 실전 문제 풀이 - The Report Problem by Hacker Rank
1. Basic Join & Advanced Select
1-1. Basic Join.
이 부분은 Table을 병합하는 방법입니다. 자세한 사항은 이전 게시글에 올려놨으니, 해당 URL을 참조해보시기 바랍니다.
이 문제에서 활용할 join 방법은 inner join입니다. 즉 두 테이블 간 공유하고 있는 데이터만 불러와도 상관이 없다는 것이죠.
1-2. Advanced Select - Case When then ~ 구문
Select 문에서 단순히 Column만 불러오는 경우만 있으면 좋겠지만, 다양한 경우가 있습니다.
예를 들어, 100점 만점짜리 수학 시험을 본다고 합시다. 굳이 0점부터 100점가지 100가지의 분류로 20~30명 학생들을 관리할 필요가 없는 경우가 많겠죠??
대충 0~40점은 하위권, 40~70점은 중위권, 그리고 70점 이상은 상위권 이렇게 나누고 싶은 경우도 있을 겁니다. 그러면 어떻게 하면 이것을 SQL에서 구현할 수 있을까요?
정답은 if 문 또는 Case 문입니다. If문은 다른 경우에 다루고 이번에는 Case문에 대해서만 다루도록 하겠습니다.
Case문은 Column값을 원하는 범위대로 혹은 원하는 조건대로 Column 값을 다양하게 분류할 수 있다는 것입니다.
중요한 포인트를 이렇게 정리할 수 있겠네요.
(1) Case 활용 목적
: 하나의 값을 원하는 범위 혹은 조건대로 재분류하기 위해서
(2) 기본 문법
Case when 조건1 then 출력값1
when 조건2 then 출력값2
.....(조건은 프로그래머가 원하는 만큼 넣을 수 있습니다.)
Else 이하 다른 경우의 수
END
이러한 조건이 어떻게 쓰일 수 있는지 실제 문제를 통해서 살펴보도록 하겠습니다.
2. 실전 문제 풀이 - Basic Join & Advanced Select (The Report) - 난이도 중
문제 링크: The Report by HackerRank
<실제 문제 입니다. 급하신 분들은 및에 한글로 문제 사항 한줄 요약 해놨으니 그것만 보세요>
You are given two tables: Students and Grades. Students contains three columns ID, Name and Marks.
Ketty gives Eve a task to generate a report containing three columns: Name, Grade and Mark. Ketty doesn't want the NAMES of those students who received a grade lower than 8. The report must be in descending order by grade -- i.e. higher grades are entered first. If there is more than one student with the same grade (8-10) assigned to them, order those particular students by their name alphabetically. Finally, if the grade is lower than 8, use "NULL" as their name and list them by their grades in descending order. If there is more than one student with the same grade (1-7) assigned to them, order those particular students by their marks in ascending order.
Write a query to help Eve.
Sample Input
Sample Output
Maria 10 99
Jane 9 81
Julia 9 88
Scarlet 8 78
NULL 7 63
NULL 7 68
(1) 문제 요구 사항 정리
1. 이름 / 등급 / 성적 순으로 나열 해라
2. 7등급 이하는 이름을 Null로 해라
3. 나열 순서는 등급(DESC), 이름(ASC), 점수(ASC)
(2) 손코드 계획
항상 실제 코딩이 들어가기 전에 배워왔던 문법과 기본 논리로 손코드 계획을 짜보는 연습을 해보세요. 정말 정말 코드 실력 느는데 이것만한게 없는 것 같아요.
손코드라고 해서 반드시 연습장에 써야 되는 것은 아니에요. 저는 그렇게 하긴 하는데, 머리 속으로 어떻게 코드를 짤지 한 번 큰 계획을 세운다는 것에 목적을 두고 하는 것입니다.
Select 이름 / 등급 / 점수
from Student 데이터
Join Grade / 점수를 나눌 수 있는 범위 지정하기
Where 등급이 7등급이 이상인 학생만 이름을 제대로 불러와줘
order by 문제의 요구대로 배열;
자 그럼 이런 계획대로 코딩을 시작을 하는 것입니다. 물론 실제 답안을 작성하는 과정에서는 구체적인 논리 순서는 바뀔 수 있으나, 이런 큰 그림을 갖고 가는지 그냥 가는지는 엄청난 차이를 불러와요.
그럼 실제 답안을 보도록 하겠습니다.
(3) 답안 작성 및 해설
1
2
3
4
5
6
7
8
|
SELECT
(CASE WHEN G.Grade > 7 THEN S.Name
ELSE 'NULL' END) AS student_name , G.Grade
, S.Marks
FROM Students S
JOIN Grades G ON S.Marks BETWEEN G.Min_Mark AND G.Max_Mark
ORDER BY G.Grade DESC, student_name ASC, S.Marks ASC;
|
cs |
1) 개념의 적용
- Inner Join
우선 여기서 Inner Join을 할 때 범위를 Point로 합병할 경우 between 문을 활용할 수 있다는 것입니다.
Point1. 테이블의 병합
Join Grades G on S.Marks
-> 여기까지는 Grades라는 테이블을 합칠 예정인데, Student의 Marks와 합칠 거야.
bewteen G.Min_Mark AND G.Max_Mark
-> 근데 병합을 할 때 grade의 최소값과 최대값 사이 범위를 기준으로 할 꺼야.
이런식의 명령문도 사용가능하답니다.
보통 join을 할 때는 동일한 Column을 지정하는 경우가 많아서 column1 = column2이런식으로 합니다. 물론 이게 가장 흔한 케이스이긴 한데, 위의 경우처럼 범위로도 지정할 수 있다는 사실을 알아두면 정말 좋습니다.
- Case when의 적용
Case -> 자 이제 내가 조건을 적용하기 시작할꺼야
WHEN G.Grade > 7 THEN S.Name -> 등급이 7등급 이상인 애들은 이름을 정상적으로 불러오고
ELSE 'NULL' -> 나머지 것들은 전혀 관심이 없으니 'null'로 데리고와
End -> 조건문 끝났고
AS student_name -> 이 Column의 이름은 student_name이야.
이런 식으로 코드를 풀이할 수 있겠네요.
실제 답안을 작성하다 보니 inner join과 case when 문에서 자연스럽게 where 조건까지 포함이 되어버렸네요. 그래서 손코드의 where은 생략했습니다.
여러분도 다양한 방법으로 활용해보시기 바래요.
항상 정독하지 마시고, 원하는 부분만 쏙 골라서 읽고 가세요!! 시간을 우리 절약해보아요 ㅋㅋㅋ
'SQL - Mysql & Oracle' 카테고리의 다른 글
[SQL] 프로그래머스 - 최댓값 구하기 해설(feat. 집계함수 모음) (0) | 2022.06.03 |
---|---|
SQL - 프로그래머스 - 입양 시각구하기(2) (0) | 2021.04.03 |
SQL - 실전 문제 풀이(Basic Aggregation / 집계함수) - 난이도 하 (0) | 2020.10.27 |
SQL - 실전 문제 풀이(Basic & Advanced Join) - 난이도 하 (0) | 2020.10.15 |