프로그래머스 SQL 코딩테스트 문제풀이: ORACLE
프로그래머스 SQL 코딩테스트 문제풀이: ORACLE
- 프로그래머스 SQL 코딩테스트 연습문제는 두가지 방식으로 풀수 있습니다. Oracle 그리고 MySQL.
- 두 DB의 SQL 쿼리가 다소 차이가 있습니다. 저는 Oracle을 주로 해왔으니 Oracle을 이용한 문제 풀이를 해보겠습니다.
모든 레코드 조회
- 가장 기초적인
SELECT
구문과 order by 를 이용한 정렬을 사용할 수 있는 묻는 문제입니다. order by 구문은 컬럼명을 직접 줘도 되고, 컬럼 순번을 기입해도 됩니다.SELECT * FROM ANIMAL_INS order by 1;
역순 정렬 하기
- order by 절에 DESC (오름차순) 구문을 이용할 수 있는가에 대한 문제입니다.
SELECT name, datetime FROM ANIMAL_INS order by ANIMAL_ID DESC;
아픈동물 찾기
- 조건절(where)을 사용할 수 있는지 묻는 문제입니다.
SELECT animal_id, name from animal_ins where INTAKE_CONDITION = 'Sick' order by ANIMAL_ID;
어린동물 찾기
- 조건절을 사용할 때 not 또는 ! 를 사용할 수 있는가를 묻는 문제입니다.
- 구문에서 NOT [컬럼] = ‘[VALUE]’ 로 조회하는것과 != 를 사용하는 것은 같은 결과 값을 가지지만 두 구문이 SQL을 처리하는데 있어 차이점이 있습니다.그건 나중에 알아보도록 합시다.
SELECT animal_id, name from animal_ins where INTAKE_CONDITION != 'Aged' order by 1;
동물 아이디와 이름
- SELECT 구문에서 특정 컬럼만 가져올 수 있는 묻는 문제입니다.
SELECT animal_id, name from animal_ins order by 1;
여러 기준으로 정렬
- order by 절을 사용할 때, 다수의 컬럼값을 기준점으로 잡아 정렬할 수 있는지를 묻는 문제입니다.
- 앞에 나열된 컬럼이 첫번째 기준점입니다. name으로 먼저 정렬을 한 상태에서 다시 시간순으로 정렬이 됩니다.
SELECT animal_id, name, datetime from animal_ins order by name, datetime desc;
상위 n개 레코드
- rownum 컬럼을 이용해서 상위 혹은 하위 n개의 결과 값을 조회할 수 있는지 묻는 문제입니다.
- MySQL의 경우
LIMIT
를 사용하면 간단한데, 오라클에서는 rownum을 이용합니다.select name from (SELECT name, datetime from animal_ins order by datetime ASC) where rownum = 1;
최대값 구하기
- MAX 함수를 사용할 수 있는지 묻는 문제입니다.
select max(datetime) from animal_ins;
최솟값 구하기
- MIN 함수를 사용할 수 있는지 묻는 문제입니다.
SELECT min(datetime) from animal_ins;
동물 수 구하기
COUNT
를 사용할 수 있는지 묻는 문제입니다.SELECT count(animal_id) from animal_ins;
중복 제거하기
- 컬럼 조회시
distinct
를 사용할 수 있는지 묻는 문제입니다.SELECT count(distinct name) "Count" from animal_ins where name is not NULL;
고양이와 개는 몇 마리 있을까
- 특정 컬럼을 group by로 묶고, count를 이용하여 몇개가 있는지 확인하는 문제입니다.
SELECT animal_type, count(*) "Count" from animal_ins group by animal_type order by 1;
동명 동물수 찾기
- 같은 이를 가진 동물은 무조건 2마리 이상이 되어야 합니다. HAVING 절을 이용하여 특정 조건을 만족하는 값을 찾을 수 있는 묻는 문제입니다.
- HAVING 절을 group by와 함께 쓰이며, 집계함수를 가지고 조건 비교를 할 때 사용합니다.
SELECT name, count(name) "count" from animal_ins where name is not NULL group by name having count(name) > 1 order by name;
입양 시각 구하기(1)
- 조건절에서 between을 이용할 수 있는지 묻는 문제입니다.
- to_char를 이용해서 datetime에서 시간만 추출합니다.
SELECT to_char(DATETIME,'HH24') "HOUR", COUNT(*) "COUNT" FROM ANIMAL_OUTS where to_char(DATETIME,'HH24') between 9 and 20 GROUP BY to_char(DATETIME,'HH24') ORDER BY 1;
입양 시각 구하기(2)
- LEVEL을 이용하여 24시간을 표현할 수 있는지 묻는 문제입니다. LEVEL은 계층구조를 표현하는 함수입니다.
- 추가로 NVL을 이용해 NULL값을 특정 값으로 치환할 수 있는지 묻는 문제입니다.
SELECT R.lv, NVL(E.cnt,0) FROM (SELECT TO_CHAR(DATETIME,'HH24') as HOUR ,COUNT(*) cnt FROM ANIMAL_OUTS GROUP BY TO_CHAR(DATETIME,'HH24') ORDER BY HOUR) E, (SELECT (LEVEL-1) lv FROM dual CONNECT BY LEVEL <=24) R WHERE R.lv = E.HOUR(+) ORDER BY R.lv;
이름이 없는 동물의 아이디
- NULL 값 조회를 묻는 문제입니다.
select ANIMAL_ID from animal_ins where name is NULL order by animal_id ASC;
이름이 있는 동물의 아이디
- 값이 존재하는 (NOT NULL ) 데이터를 조회하는 문제입니다.
SELECT animal_id from animal_ins where name is not null order by 1 asc;
NULL 처리하기
- 다중 조건을 가지고 SQL을 생성할 수 있는 묻는 문제입니다.
- CASE를 이용합니다. NULL 이면 No name을 출력하고, NULL이 아닌 경우에는 원본값을 출력합니다.
SELECT animal_type, case when name is NULL then 'No name' else name end, sex_upon_intake from animal_ins order by animal_id;
없어진 기록 찾기
- LEFT OUTER JOIN을 이용하는 문제입니다.
- LEFT OUTER JOIN은 두가지 방식으로 표현할 수 있습니다. LEFT OUTER JOIN 구문을 사용하는 것과 (+)를 사용하는 것입니다.
- 일반적으로 left outer join 에서 on 절에는 우측(null 값이 포함되는) 테이블의 제약조건을 넣고, where 절에는 좌측 테이블의 제약조건을 넣습니다.
SELECT O.animal_id, O.name FROM animal_outs O LEFT OUTER JOIN animal_ins I on O.animal_id=I.animal_id where I.animal_id is null order by O.animal_id; SELECT O.animal_id, O.name FROM animal_outs O, animal_ins I where I.animal_id(+)=O.animal_id and I.animal_id is null order by O.animal_id;
있었는데요 없었습니다.
- 조건절의 부등호를 이용해 두개의 테이블을 조인하여 차이값을 통해 결과값을 조회하는 문제입니다
SELECT a.animal_id, a.name FROM ANIMAL_INS a, ANIMAL_OUTS b where a.animal_id=b.animal_id and a.datetime > b.datetime order by a.datetime;
오랜기간 보호한 동물(1)
- LEFT OUTER JOIN을 묻는 문제입니다.
- rownum을 조합하여 원하는 개수의 결과값을 조회합니다.
select * from (SELECT a.name, a.datetime FROM ANIMAL_INS a LEFT OUTER JOIN ANIMAL_OUTS b on a.animal_id = b.animal_id where b.animal_id is null order by a.datetime) where rownum <=3; select * from (SELECT a.name, a.datetime FROM ANIMAL_INS a, ANIMAL_OUTS b where a.animal_id = b.animal_id(+) and b.animal_id is null order by a.datetime) where rownum <=3;
보호소에서 중성화 한 동물
- LEFT OUTER JOIN과 NOT 구문이 조합된 문제입니다.
SELECT b.animal_id, b.animal_type, b.name FROM animal_ins a, animal_outs b where b.animal_id = a.animal_id(+) and b.sex_upon_outcome != a.sex_upon_intake order by b.animal_id;
루시와 엘라 찾기
- 조건절에서
in
을 사용하여 원하는 값만 조회할 수 있는 묻는 문제입니다.SELECT animal_id, name, SEX_UPON_INTAKE FROM animal_ins where name in ('Lucy','Ella','Pickle','Rogan','Sabrina','Mitty') order by 1;
이름에 el이 들어가는 동물 찾기
- LIKE를 사용하여 좀 더 복잡한 조건의 값을 찾아올 수 있는 묻는 문제입니다.
- LIKE에 %를 사용하면 특정 단어가 포한된 값을 조회할 수 있습니다.
SELECT animal_id, name FROM animal_ins where animal_type='Dog' and (name like '%el%' or name like '%El%') order by name;
중성화 여부 파악하기
- CASE 문을 이용해 특정 값을 가진 데이터를 원하는 값으로 표시할 수 있는지 묻는 문제입니다.
- 특정 값은 LIKE를 이용해 조회합니다.
SELECT animal_id, name, CASE when SEX_UPON_INTAKE like 'Neutered%' then 'O' when SEX_UPON_INTAKE like 'Spayed%' then 'O' else 'X' end "중성화" FROM ANIMAL_INS order by animal_id;
오랜기간 보호한 동물(2)
- JOIN과 연산자를 이용한 시간차 계산 및 rownum을 통한 원하는 갯수만큼 결과 값을 조회하는 문제입니다.
select * from ( SELECT A.ANIMAL_ID, A.NAME FROM ANIMAL_INS A, ANIMAL_OUTS B WHERE A.ANIMAL_ID = B.ANIMAL_ID ORDER BY B.DATETIME-A.DATETIME DESC) where rownum <=2
DATETIME에서 DATE로 형 변환
- to_char를 이용해 날짜 형식을 원하는 형태로 바꿀수 있는 묻는 문제입니다.
SELECT ANIMAL_ID, name, to_char(DATETIME,'yyyy-mm-dd') FROM ANIMAL_INS order by ANIMAL_ID;
프로그래머스의 SQL 문제는 굉장히 기초적인 문제들입니다.
SQL 사용에 있어서 대부분 필수적인 부분을 물어보기 때문에 그리 어렵지 않고, DB를 하는데 알아두면 도움이 많이 될거라 생각이 듭니다.
최신 댓글