프로그래머스를 활용한 SQL 배우기

Lee Sang Hyuk·2022년 3월 1일

Database

목록 보기
1/1
post-thumbnail

https://techskill.sg/wp-content/uploads/2020/06/SQL-server.jpg

SQL이란?

SQL는 관계형 데이터베이스 관리 시스템(RDBMS)의 데이터를 관리하기 위해 설계된 특수 목적의 프로그래밍 언어이다. 관계형 데이터베이스 관리 시스템에서 자료의 검색과 관리, 데이터베이스 스키마 생성과 수정, 데이터베이스 객체 접근 조정 관리를 위해 고안되었다.

< 위키백과, https://ko.wikipedia.org/wiki/SQL >

공부 방법?

사실, 학교에서 데이터베이스 수업 때 어느 정도 알고 있는 개념은 있었지만 막상 실전에서 사용하려고 생각하면 몸이 잘 따라주지 못해서 다시 한번 복습 차원으로 공부하게 되었다. 또한, 소프트웨어 마에스트로를 지원하게 되면서 코딩테스트 중 SQL 문제가 출제된다는 소식에 단기간으로 공부할 수 있는 방법을 찾다가 프로그래머스에 있는 “SQL 고득점 Kit” 기반으로 공부하면 쿼리 부분에 대해서 괜찮다고 느껴 직접 풀어보고, 정리하는 식으로 진행했다.

<프로그래머스 “SQL 고득점 Kit”, https://programmers.co.kr/learn/challenges?tab=sql_practice_kit>

파트별 내용

(※ 모든 코드의 컴파일 버전은 “MySQL” 기준입니다.)

SELECT

해당된 테이블의 모든 또는 특정 열을 선택하는 구문

추가적으로 배운 구문

  • 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개 레코드
-- 출저 : 프로그래머스, "상위 n개 레코드" 문제
-- 링크 : https://programmers.co.kr/learn/courses/30/lessons/59405

SELECT NAME
FROM ANIMAL_INS
ORDER BY DATETIME
LIMIT 1

SUM, MAX, MIN

해당된 테이블 중 특정 레코드에 대한 계산식 데이터 표현

추가적으로 배운 구문

  • 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

GROUP BY

특정 열을 그룹화하는 구문

추가적으로 배운 구문

  • 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)
-- 출저 : 프로그래머스, "입양 시각 구하기(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)
-- 출저 : 프로그래머스, "입양 시각 구하기(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에 넣겠다는 의미이다.

IS NULL

해당된 필드 값이 비여있을 경우(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 처라하기
-- 출저 : 프로그래머스, "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

다른 테이블과 병합하는 구문

추가적으로 배운 구문

  • JOIN : 다른 테이블과 병합하는 구문 (※ 생략 시, 설정된 Default값 + 합집합)
    • LEFT JOIN : 왼쪽 부분 집합
    • RIGHT JOIN : 오른쪽 부분 집합
    • INNER JOIN : 교집합

https://user-images.githubusercontent.com/32683894/91840106-1d099d00-ec8b-11ea-87d0-248be6b55a46.png

  • 없어진 기록 찾기
-- 출저 : 프로그래머스, "없어진 기록 찾기" 문제
-- 링크 : 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)
-- 출저 : 프로그래머스, "오랜 기간 보호한 동물(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

String, Date

추가적으로 배운 구문

  • 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이 들어가는 동물 찾기
-- 출저 : 프로그래머스, "이름에 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)
-- 출저 : 프로그래머스, "오랜 기간 보호한 동물(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로 형 변환
-- 출저 : 프로그래머스, "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
profile
개발자가 될 수 있을까?

0개의 댓글