


“ SQL는 관계형 데이터베이스 관리 시스템(RDBMS)의 데이터를 관리하기 위해 설계된 특수 목적의 프로그래밍 언어이다. 관계형 데이터베이스 관리 시스템에서 자료의 검색과 관리, 데이터베이스 스키마 생성과 수정, 데이터베이스 객체 접근 조정 관리를 위해 고안되었다. ”
< 위키백과, https://ko.wikipedia.org/wiki/SQL >
사실, 학교에서 데이터베이스 수업 때 어느 정도 알고 있는 개념은 있었지만 막상 실전에서 사용하려고 생각하면 몸이 잘 따라주지 못해서 다시 한번 복습 차원으로 공부하게 되었다. 또한, 소프트웨어 마에스트로를 지원하게 되면서 코딩테스트 중 SQL 문제가 출제된다는 소식에 단기간으로 공부할 수 있는 방법을 찾다가 프로그래머스에 있는 “SQL 고득점 Kit” 기반으로 공부하면 쿼리 부분에 대해서 괜찮다고 느껴 직접 풀어보고, 정리하는 식으로 진행했다.

<프로그래머스 “SQL 고득점 Kit”, https://programmers.co.kr/learn/challenges?tab=sql_practice_kit>
(※ 모든 코드의 컴파일 버전은 “MySQL” 기준입니다.)
해당된 테이블의 모든 또는 특정 열을 선택하는 구문
추가적으로 배운 구문
FROM : 테이블 선택하는 구문
ORDER BY : 선택한 열 중심으로 정렬
ASC : 오름차순으로 정렬 (※ 생략 시, 설정된 Default값)DESC : 내림차순으로 정렬WHERE : 특정 조건에 맞는 데이터 조회 (※ 프로그래밍 중에서 “IF문" 개념과 유사)
LIMIT : 레코드 출력 개수 제한
모든 레코드를 조회하는 방법
-- 출저 : 프로그래머스, "모든 레코드를 조회하는 방법" 문제
-- 링크 : https://programmers.co.kr/learn/courses/30/lessons/59034
SELECT *
FROM ANIMAL_INS
ORDER BY ANIMAL_ID
-- 출저 : 프로그래머스, "역순 정렬하기" 문제
-- 링크 : https://programmers.co.kr/learn/courses/30/lessons/59035
SELECT NAME, DATETIME
FROM ANIMAL_INS
ORDER BY ANIMAL_ID DESC
-- 출저 : 프로그래머스, "아픈 동물 찾기" 문제
-- 링크 : https://programmers.co.kr/learn/courses/30/lessons/59036
SELECT ANIMAL_ID, NAME
FROM ANIMAL_INS
WHERE INTAKE_CONDITION = "Sick"
-- 출저 : 프로그래머스, "어린 동물 찾기" 문제
-- 링크 : https://programmers.co.kr/learn/courses/30/lessons/59037
SELECT ANIMAL_ID, NAME
FROM ANIMAL_INS
WHERE INTAKE_CONDITION != "Aged"
ORDER BY ANIMAL_ID
-- 출저 : 프로그래머스, "동물의 아이디와 이름" 문제
-- 링크 : https://programmers.co.kr/learn/courses/30/lessons/59403
SELECT ANIMAL_ID, NAME
FROM ANIMAL_INS
ORDER BY ANIMAL_ID
-- 출저 : 프로그래머스, "여러 기준으로 정렬하기" 문제
-- 링크 : https://programmers.co.kr/learn/courses/30/lessons/59404
SELECT ANIMAL_ID, NAME, DATETIME
FROM ANIMAL_INS
ORDER BY NAME ASC, DATETIME DESC
-- 출저 : 프로그래머스, "상위 n개 레코드" 문제
-- 링크 : https://programmers.co.kr/learn/courses/30/lessons/59405
SELECT NAME
FROM ANIMAL_INS
ORDER BY DATETIME
LIMIT 1
해당된 테이블 중 특정 레코드에 대한 계산식 데이터 표현
추가적으로 배운 구문
MAX : 선택한 열의 최댓값
MIN : 선택한 열의 최솟값
COUNT : 선택한 열의 개수
DISTINCT : 선택한 열의 명칭 중 중복되지 않고 별개의 자료로 추출
AS : 선택한 열의 별칭 선언
최댓값 구하기
-- 출저 : 프로그래머스, "최댓값 구하기" 문제
-- 링크 : https://programmers.co.kr/learn/courses/30/lessons/59415
SELECT MAX(DATETIME) AS 시간
FROM ANIMAL_INS
-- 출저 : 프로그래머스, "최솟값 구하기" 문제
-- 링크 : https://programmers.co.kr/learn/courses/30/lessons/59038
SELECT MIN(DATETIME) AS 시간
FROM ANIMAL_INS
-- 출저 : 프로그래머스, "동물 수 구하기" 문제
-- 링크 : https://programmers.co.kr/learn/courses/30/lessons/59406
SELECT COUNT(ANIMAL_ID)
FROM ANIMAL_INS
-- 출저 : 프로그래머스, "중복 제거하기" 문제
-- 링크 : https://programmers.co.kr/learn/courses/30/lessons/59408
SELECT COUNT(DISTINCT(NAME))
FROM ANIMAL_INS
특정 열을 그룹화하는 구문
추가적으로 배운 구문
HAVING : 특정 열을 그룹화한 결과에 조건을 조회(※ WHERE는 그룹화 전, HAVING는 그룹화 후)
SET : 이 구문은 아래 코드에 추가로 설명
고양이와 개는 몇 마리 있을까
-- 출저 : 프로그래머스, "고양이와 개는 몇 마리 있을까" 문제
-- 링크 : https://programmers.co.kr/learn/courses/30/lessons/59040
SELECT ANIMAL_TYPE, COUNT(*) AS count
FROM ANIMAL_INS
GROUP BY ANIMAL_TYPE
ORDER BY ANIMAL_TYPE
-- 출저 : 프로그래머스, "동명 동물 수 찾기" 문제
-- 링크 : https://programmers.co.kr/learn/courses/30/lessons/59041
SELECT NAME, COUNT(*) AS COUNT
FROM ANIMAL_INS
GROUP BY NAME
HAVING COUNT(NAME) >= 2
ORDER BY NAME
-- 출저 : 프로그래머스, "입양 시각 구하기(1)" 문제
-- 링크 : https://programmers.co.kr/learn/courses/30/lessons/59412
SELECT HOUR(DATETIME) AS HOUR, COUNT(*) AS COUNT
FROM ANIMAL_OUTS
GROUP BY HOUR
HAVING HOUR >= 9 AND HOUR < 20
ORDER BY HOUR
-- 출저 : 프로그래머스, "입양 시각 구하기(2)" 문제
-- 링크 : https://programmers.co.kr/learn/courses/30/lessons/59413
SET @hour := -1;
SELECT (@hour := @hour + 1) AS HOUR,
(SELECT COUNT(*) FROM ANIMAL_OUTS WHERE HOUR(DATETIME) = @hour) AS COUNT
FROM ANIMAL_OUTS
WHERE @hour < 23;
이 문제는 좀 난이도가 있다고 느껴졌고 생소한 구문들이 있어서 추가로 설명해야 할 것 같다.
여기서 말한 SET 은 SQL에서 ‘변수 할당'의 역할이라고 말할 수 있으며 변수 이름은 꼭 @변수명 형태로 선언해야 한다. 또한, SET 이외에 = 는 SQL에서 비교 연산자라고 생각하기 때문에 변수 선언 및 값 대입 같은 경우 :=를 사용한다. (SELECT COUNT(*) FROM ANIMAL_OUTS WHERE HOUR(DATETIME) = @hour)
같은 경우, 테이블 ANIMAL_OUTS에 있는 HOUR(DATETIME)의 개수를 반복적으로 파악해 @hour에 넣겠다는 의미이다.
해당된 필드 값이 비여있을 경우(NULL)를 판단해주는 구문
추가적으로 배운 구문
IFNULL(컬럼명, 변경값) : 해당된 컬럼 중 NULL값을 변경값으로 변경
이름이 없는 동물의 아이디
-- 출저 : 프로그래머스, "이름이 없는 동물의 아이디" 문제
-- 링크 : https://programmers.co.kr/learn/courses/30/lessons/59039
SELECT ANIMAL_ID
FROM ANIMAL_INS
WHERE NAME IS NULL
-- 출저 : 프로그래머스, "이름이 있는 동물의 아이디" 문제
-- 링크 : https://programmers.co.kr/learn/courses/30/lessons/59407
SELECT ANIMAL_ID
FROM ANIMAL_INS
WHERE NOT NAME IS NULL
ORDER BY ANIMAL_ID
-- 출저 : 프로그래머스, "NULL 처리하기" 문제
-- 링크 : https://programmers.co.kr/learn/courses/30/lessons/59410
SELECT ANIMAL_TYPE,
IFNULL(NAME, "No name") AS NAME,
SEX_UPON_INTAKE
FROM ANIMAL_INS
다른 테이블과 병합하는 구문
추가적으로 배운 구문
JOIN : 다른 테이블과 병합하는 구문 (※ 생략 시, 설정된 Default값 + 합집합)LEFT JOIN : 왼쪽 부분 집합RIGHT JOIN : 오른쪽 부분 집합INNER JOIN : 교집합
-- 출저 : 프로그래머스, "없어진 기록 찾기" 문제
-- 링크 : https://programmers.co.kr/learn/courses/30/lessons/59042
SELECT ANIMAL_OUTS.ANIMAL_ID, ANIMAL_OUTS.NAME
FROM ANIMAL_OUTS LEFT JOIN ANIMAL_INS
ON ANIMAL_INS.ANIMAL_ID = ANIMAL_OUTS.ANIMAL_ID
WHERE ANIMAL_INS.ANIMAL_ID IS NULL
ORDER BY ANIMAL_ID
-- 출저 : 프로그래머스, "있었는데요 없었습니다" 문제
-- 링크 : https://programmers.co.kr/learn/courses/30/lessons/59043
SELECT I.ANIMAL_ID, I.NAME
FROM ANIMAL_INS AS I JOIN ANIMAL_OUTS AS O
WHERE I.ANIMAL_ID = O.ANIMAL_ID AND I.DATETIME >= O.DATETIME
ORDER BY I.DATETIME
-- 출저 : 프로그래머스, "오랜 기간 보호한 동물(1)" 문제
-- 링크 : https://programmers.co.kr/learn/courses/30/lessons/59044
SELECT I.NAME, I.DATETIME
FROM ANIMAL_INS AS I LEFT JOIN ANIMAL_OUTS AS O ON I.ANIMAL_ID = O.ANIMAL_ID
WHERE O.ANIMAL_ID IS NULL
ORDER BY I.DATETIME
LIMIT 3
-- 출저 : 프로그래머스, "보호소에서 중성화한 동물" 문제
-- 링크 : https://programmers.co.kr/learn/courses/30/lessons/59045
SELECT O.ANIMAL_ID, O.ANIMAL_TYPE, O.NAME
FROM ANIMAL_INS AS I RIGHT JOIN ANIMAL_OUTS AS O ON I.ANIMAL_ID = O.ANIMAL_ID
WHERE I.SEX_UPON_INTAKE != O.SEX_UPON_OUTCOME
추가적으로 배운 구문
IN : WHERE절 내에서 선택한 특정값 구문
LIKE : 부분적으로 일치하는 칼럼명 찾을 수 있는 구문
% : 글자수 제한 없이 어떠한 문자 가능_ : 선언한 만큼의 글자수 제한으로 어떠한 문자 가능IF(조건, True값, False값) : 조건이 충족할 경우, True 값 아닐 경우 False 값
DATE_FORMAT(칼럼명, 변경 형식) : 칼럼명의 날짜 포맷 형식을 바꾼다.
루시와 엘라 찾기
-- 출저 : 프로그래머스, "루시와 엘라 찾기" 문제
-- 링크 : https://programmers.co.kr/learn/courses/30/lessons/59046
SELECT ANIMAL_ID, NAME, SEX_UPON_INTAKE
FROM ANIMAL_INS
WHERE NAME IN ("Lucy", "Ella", "Pickle", "Rogan", "Sabrina", "Mitty")
-- 출저 : 프로그래머스, "이름에 el이 들어가는 동물 찾기" 문제
-- 링크 : https://programmers.co.kr/learn/courses/30/lessons/59047
SELECT ANIMAL_ID, NAME
FROM ANIMAL_INS
WHERE NAME LIKE "%el%" AND ANIMAL_TYPE = "Dog"
ORDER BY NAME
-- 출저 : 프로그래머스, "중성화 여부 파악하기" 문제
-- 링크 : https://programmers.co.kr/learn/courses/30/lessons/59049
SELECT ANIMAL_ID, NAME,
IF(SEX_UPON_INTAKE LIKE "%NEUTERED%" OR SEX_UPON_INTAKE LIKE "%SPAYED%", "O", "X") AS 중성화
FROM ANIMAL_INS
ORDER BY ANIMAL_ID
-- 출저 : 프로그래머스, "오랜 기간 보호한 동물(2)" 문제
-- 링크 : https://programmers.co.kr/learn/courses/30/lessons/59411
SELECT O.ANIMAL_ID, O.NAME
FROM ANIMAL_INS AS I JOIN ANIMAL_OUTS AS O
WHERE I.ANIMAL_ID = O.ANIMAL_ID
ORDER BY O.DATETIME - I.DATETIME DESC
LIMIT 2
-- 출저 : 프로그래머스, "DATETIME에서 DATE로 형 변환" 문제
-- 링크 : https://programmers.co.kr/learn/courses/30/lessons/59414
SELECT ANIMAL_ID, NAME, DATE_FORMAT(DATETIME, "%Y-%m-%d") AS 날짜
FROM ANIMAL_INS
ORDER BY ANIMAL_ID