프로그래머스 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를 하는데 알아두면 도움이 많이 될거라 생각이 듭니다.

 

 

 

You may also like...

댓글 남기기

이메일은 공개되지 않습니다. 필수 입력창은 * 로 표시되어 있습니다