JS' 공부흔적

[SQL] 주요 문법 1 (feat.Oracle) 본문

SQL

[SQL] 주요 문법 1 (feat.Oracle)

이준수 2023. 9. 29. 00:35

프로그래머스에서 SQL 문제를 몇 개 풀어보면서 되새겨본 주요 문법을 정리하고자 한다.

이번 글에서는 아래 5가지 문법에 대해 알아보자!

  1. LIKE
  2. TO_CHAR
  3. NOT
  4. IS NULL
  5. ROWNUM

LIKE

부분적으로 일치하는 컬럼을 찾을 때 사용된다. 크게 2가지로 구성된다.

  1. _ : 글자 수를 정해준다.
  2. % : 글자 수를 정해주지 않는다.

몇 가지 예시를 살펴보자.

-- '인천'으로 시작하는 주소
SELECT ADDRESS
FROM FOOD_FACTORY
WHERE ADDRESS LIKE '인천%'

-- '송도동'으로 끝나는 주소
SELECT ADDRESS
FROM FOOD_FACTORY
WHERE ADDRESS LIKE '%송도동'

-- '서울'을 포함하는 주소
SELECT ADDRESS
FROM FOOD_FACTORY
WHERE ADDRESS LIKE '%서울%'

-- '서'로 시작하는 3글자 주소
SELECT ADDRESS
FROM FOOD_FACTORY
WHERE ADDRESS LIKE '서__'

 

이때 대소문자 구분 없이 모두 조회해야 하는 경우가 있다. 예를 들면, 대소문자 구분 없이 'el'을 포함하는 문자열을 조회해라! 라고 한다면 아래와 같이 구분하면 된다.

UPPER(필드명) LIKE '%EL%'
-- 또는
LOWER(필드명) LIKE '%el%'

TO_CHAR

나는 주로 날짜를 포맷할 때 사용했다. 이 문제를 예시로 들겠다.

2021년에 출판된 인문 카테고리에 속하는 도서 리스트를 찾아야 한다.

그럼 출판일에서 '2021'을 찾아야 한다. 보다시피 PUBLISHED_DATE의 Type은 DATE이므로 이를 가공하기 위해선 CHAR로 바꿔야 하는데, 이때 TO_CHAR을 사용한다.

TO_CHAR은 필드명을 작성한 후에 포맷 형식을 정할 수 있다. 아래 예시를 보자.

TO_CHAR(PUBLISHED_DATE,'YYYY') -- ex) 2021
TO_CHAR(PUBLISHED_DATE,'YYYY-MM-DD') -- ex) 2021-03-21
TO_CHAR(PUBLISHED_DATE, 'YYYY-MM-DD HH24:MI:SS') -- ex) 2021-03-21 13:30:00

여기서 아이디어를 얻을 수 있을 것 같다! 출판일에서 연도만 뽑아내고 이 값이 '2021'인 것만 찾으면 된다.

그럼 문제에서 요구하는 대로 코드를 작성하면 아래와 같다.

SELECT BOOK_ID, TO_CHAR(PUBLISHED_DATE,'YYYY-MM-DD')
FROM BOOK
WHERE TO_CHAR(PUBLISHED_DATE,'YYYY')='2021' AND CATEGORY='인문'
ORDER BY PUBLISHED_DATE ASC

SELECT 구문에서도 TO_CHAR이 쓰였는데, 이는 날짜 포맷을 예시와 맞추기 위함이다.


NOT과 IS NULL

이 2가지는 쉽기도 하고, 함께 쓰이는 경우가 있어서 같이 설명하겠다.

이름에서도 짐작할 수 있듯이 NOT은 부정하는 문법, IS NULL은 NULL인지 확인하는 문법이다.

예시로는 이 문제를 확인해보자!

이름이 있는 동물의 ID를 조회하라고 한다.

NAME의 NULLABLE이 TRUE이므로 NULL 값이 들어갈 수 있다는 뜻이다. 따라서 이름이 있는 동물을 조회하라는 것은 이름이 NULL이 아닌 동물을 조회하라는 말과 같다. 이때 NOT과 IS NULL을 같이 쓰면 해결할 수 있어보인다!

SELECT ANIMAL_ID
FROM ANIMAL_INS
WHERE NOT NAME IS NULL 또는 WHERE NAME IS NOT NULL
ORDER BY ANIMAL_ID

사실 IS NOT NULL로 작성해도 됐네 ㅎㅎ


ROWNUM

말 그대로 ROW의 넘버를 의미한다.

나는 이 문제에서 상위 n개의 필드를 조회할 때 이 개념을 사용했다. DB에서 데이터를 조회하게 되면 ROWNUM이 1, 2, 3, ... 순서대로 매겨지게 된다. 이때 상위 3개의 필드를 조회하라고 하면 ROWNUM<=3인 것만 걸러주면 되는 것이다.

가장 먼저 들어온 동물의 이름을 조회, 즉 DATETIME을 기준으로 오름차순 정렬한 후에 상위 1개의 데이터만 추출하면 된다.

SELECT NAME
FROM ANIMAL_INS
WHERE ROWNUM=1
ORDER BY DATETIME

위처럼 작성하면 될 것 같다!

 

근데 틀렸다.

 

ROWNUM은 쿼리가 완전히 수행되기 전, 즉 원래 데이터의 정렬 순서대로 번호를 매긴다.

따라서 DATETIME을 기준으로 정렬되기 전에 출력이 되기 때문에 의도하지 않은 결과가 나온다.

이를 방지하기 위해서 전체 코드를 한 번 감싸야 한다.

SELECT *
FROM (SELECT NAME
FROM ANIMAL_INS
ORDER BY DATETIME)
WHERE ROWNUM=1

 

참고로 MySQL에서는 LIMIT를 사용하여 아래처럼 쉽게 가능하다고 한다^^..

SELECT NAME
FROM ANIMAL_INS
ORDER BY DATETIME
LIMIT 1

 

728x90
반응형