DB, SQL

[프로그래머스] SQL SELECT문

RuBPCase 2022. 1. 29. 11:46
728x90

원본 링크

https://programmers.co.kr/learn/courses/30/parts/17042

개요

알고리즘과 별도로 SQL문을 사용하는 연습을 수행하려 한다.
따라서 우선 프로그래머스 사이트에 있는 예제들을 토대로 하나씩 복기하며 리마인드할 생각이다.
코드가 그렇게 복잡하지 않은 이상 아마 여러 문제를 하나의 게시물로 올릴 것 같다.
지금도 그러하다.

여기에선 SELECT문을 사용하는 문제를 주로 풀 것이다.
기본은 SELECT문을 기반으로 쓰지만, 필요에 따라서 ORDER BY, WHERE절 등의 친구도 같이 써야한다.
이러한 요소들은 문제에서 나오면 따로 설명할 생각이다.

공통 조건

ANIMAL_INS 테이블은 동물 보호소에 들어온 동물의 정보를 담은 테이블입니다. ANIMAL_INS 테이블 구조는 다음과 같으며, ANIMAL_ID, ANIMAL_TYPE, DATETIME, INTAKE_CONDITION, NAME, SEX_UPON_INTAKE는 각각 동물의 아이디, 생물 종, 보호 시작일, 보호 시작 시 상태, 이름, 성별 및 중성화 여부를 나타냅니다.

NAME TYPE NULLABLE
ANIMAL_ID VARCHAR(N) FALSE
ANIMAL_TYPE VARCHAR(N) FALSE
DATETIME DATETIME FALSE
INTAKE_CONDITION VARCHAR(N) FALSE
NAME VARCHAR(N) TRUE
SEX_UPON_INTAKE VARCHAR(N) FALSE

문제 1 (모든 레코드 조회하기)

동물 보호소에 들어온 모든 동물의 정보를 ANIMAL_ID순으로 조회하는 SQL문을 작성해주세요. SQL을 실행하면 다음과 같이 출력되어야 합니다.

ANIMAL_ID ANIMAL_TYPE DATETIME INTAKE_CONDITION NAME SEX_UPON_INTAKE
A349996 Cat 2018-01-22 14:32:00 Normal Sugar Neutered Male
A350276 Cat 2017-08-13 13:50:00 Normal Jewel Spayed Female
A350375 Cat 2017-03-06 15:01:00 Normal Meo Neutered Male
A352555 Dog 2014-08-08 04:20:00 Normal Harley Spayed Female
..이하 생략

나만의 풀이 1

크게 설명할 내용은 없다.
모든 정보를 출력하되, ANIMAL_ID순으로 조회만 하면 된다.
따라서 SELECT문에 ORDER BY문을 넣어서 정렬 후 출력을 해주면 된다.
게다가 오름차순 정렬이니 추가 조건도 붙을 필요가 없다.

SELECT * FROM ANIMAL_INS
ORDER BY ANIMAL_ID

문제 2 (역순 정렬하기)

동물 보호소에 들어온 모든 동물의 이름과 보호 시작일을 조회하는 SQL문을 작성해주세요. 이때 결과는 ANIMAL_ID 역순으로 보여주세요. SQL을 실행하면 다음과 같이 출력되어야 합니다.

NAME DATETIME
Rocky 2016-06-07 09:17:00
Shelly 2015-01-29 15:01:00
Benji 2016-04-19 13:28:00
Jackie 2016-01-03 16:25:00
*Sam 2016-03-13 11:17:00
..이하 생략

나만의 풀이 2

아까 문제 1에서 코드 조금만 추가해주면 된다.
이번엔 모든 속성이 아닌 NAMEDATETIME 속성만을 뽑아내면 된다.
그리고 역순으로 출력해야 하므로 DESC라는 속성을 ORDER BY 뒤에 넣기만 하면 된다.

SELECT NAME, DATETIME FROM ANIMAL_INS
ORDER BY ANIMAL_ID DESC

문제 3 (아픈 동물 찾기)

동물 보호소에 들어온 동물 중 아픈 동물의 아이디와 이름을 조회하는 SQL 문을 작성해주세요. 이때 결과는 아이디 순으로 조회해주세요.
(INTAKE_CONDITION이 Sick인 경우를 뜻함)

예를 들어 ANIMAL_INS 테이블이 다음과 같다면

ANIMAL_ID ANIMAL_TYPE DATETIME INTAKE_CONDITION NAME SEX_UPON_INTAKE
A365172 Dog 2014-08-26 12:53:00 Normal Diablo Neutered Male
A367012 Dog 2015-09-16 09:06:00 Sick Miller Neutered Male
A365302 Dog 2017-01-08 16:34:00 Aged Minnie Spayed Female
A381217 Dog 2017-07-08 09:41:00 Sick Cherokee Neutered Male

이 중 아픈 동물은 Miller와 Cherokee입니다. 따라서 SQL문을 실행하면 다음과 같이 나와야 합니다.

ANIMAL_ID NAME
A367012 Miller
A381217 Cherokee

나만의 풀이 3

드디어 SELECT하면 쌍으로 따라오는 WHERE라는 친구를 사용하게 됐다.
알다시피 우리가 흔히 쓰는 SELECT문의 구조는 다음과 같다.

SELECT (속성명) FROM (테이블명) WHERE (조건명)

그냥 위 형태대로 주어진 문제에 맞춰 코드를 짜면 된다.
다만, 유의사항은 SQL은 '같다'라는 연산이 '=='가 아닌 '='를 쓴다는 것이다.
이 점만 유의하면 된다.

SELECT ANIMAL_ID, NAME FROM ANIMAL_INS
WHERE INTAKE_CONDITION = 'Sick'
ORDER BY ANIMAL_ID

문제 4 (어린 동물 찾기)

동물 보호소에 들어온 동물 중 젊은 동물의 아이디와 이름을 조회하는 SQL 문을 작성해주세요. 이때 결과는 아이디 순으로 조회해주세요.
(INTAKE_CONDITION이 Aged가 아닌 경우를 뜻함)

예를 들어 ANIMAL_INS 테이블이 다음과 같다면

ANIMAL_ID ANIMAL_TYPE DATETIME INTAKE_CONDITION NAME SEX_UPON_INTAKE
A365172 Dog 2014-08-26 12:53:00 Normal Diablo Neutered Male
A367012 Dog 2015-09-16 09:06:00 Sick Miller Neutered Male
A365302 Dog 2017-01-08 16:34:00 Aged Minnie Spayed Female
A381217 Dog 2017-07-08 09:41:00 Sick Cherokee Neutered Male

이 중 젊은 동물은 Diablo, Miller, Cherokee입니다. 따라서 SQL문을 실행하면 다음과 같이 나와야 합니다.

ANIMAL_ID NAME
A365172 Diablo
A367012 Miller
A381217 Cherokee

나만의 풀이 4

문제 3의 응용 버전이다.
이번엔 같다가 아닌 다르다라는 조건을 사용하므로, = 대신 !=를 써주면 된다.

SELECT ANIMAL_ID, NAME FROM ANIMAL_INS
WHERE INTAKE_CONDITION != 'Aged'
ORDER BY ANIMAL_ID

문제 5 (동물의 아이디와 이름)

동물 보호소에 들어온 모든 동물의 아이디와 이름을 ANIMAL_ID순으로 조회하는 SQL문을 작성해주세요. SQL을 실행하면 다음과 같이 출력되어야 합니다.

ANIMAL_ID NAME
A349996 Sugar
A350276 Jewel
A350375 Meo
A352555 Harley
A352713 Gia
A352872 Peanutbutter
A353259 Bj
((이하생략))

나만의 풀이 5

크게 어렵지 않으므로 설명은 생략한다.
사실 아까 문제보다 이 문제가 먼저 나와야 순서가 맞다 생각이 든다.

SELECT ANIMAL_ID, NAME FROM ANIMAL_INS
ORDER BY ANIMAL_ID

문제와는 별개로 이름이 Peanutbutter인 친구가 있다. (땅콩버터....)

문제 6 (여러 기준으로 정렬하기)

동물 보호소에 들어온 모든 동물의 아이디와 이름, 보호 시작일을 이름 순으로 조회하는 SQL문을 작성해주세요. 단, 이름이 같은 동물 중에서는 보호를 나중에 시작한 동물을 먼저 보여줘야 합니다.

예를 들어, ANIMAL_INS 테이블이 다음과 같다면

ANIMAL_ID ANIMAL_TYPE DATETIME INTAKE_CONDITION NAME SEX_UPON_INTAKE
A349996 Cat 2018-01-22 14:32:00 Normal Sugar Neutered Male
A350276 Cat 2017-08-13 13:50:00 Normal Jewel Spayed Female
A396810 Dog 2016-08-22 16:13:00 Injured Raven Spayed Female
A410668 Cat 2015-11-19 13:41:00 Normal Raven Spayed Female
  1. 이름을 사전 순으로 정렬하면 다음과 같으며, 'Jewel', 'Raven', 'Sugar'
  2. 'Raven'이라는 이름을 가진 개와 고양이가 있으므로, 이 중에서는 보호를 나중에 시작한 개를 먼저 조회합니다.

따라서 SQL문을 실행하면 다음과 같이 나와야 합니다.

ANIMAL_ID NAME DATETIME
A350276 Jewel 2017-08-13 13:50:00
A396810 Raven 2016-08-22 16:13:00
A410668 Raven 2015-11-19 13:41:00
A349996 Sugar 2018-01-22 14:32:00

나만의 풀이 6

아주 살짝 꼬아놓은 문제이다.
왜냐하면 2가지 속성을 조합해서 정렬하라 되어있기 때문이다.
크게 별거 없고, ORDER BY문에서 총 2개의 속성을 고려해주면 된다.

먼저 이름을 사전 순으로 정렬하라 했으므로 맨 처음에 NAME을 쓰면 된다.
다음에 동일 이름이 있는 경우 나중에 보호를 시작한 동물부터 정렬하라 하므로 DATETIME DESC를 추가로 써주면 된다.
즉, NAME 먼저, DATETIME은 그 다음이 된다.

SELECT ANIMAL_ID, NAME, DATETIME FROM ANIMAL_INS
ORDER BY NAME, DATETIME DESC

문제 7 (상위 n개 레코드)

동물 보호소에 가장 먼저 들어온 동물의 이름을 조회하는 SQL 문을 작성해주세요.

예를 들어 ANIMAL_INS 테이블이 다음과 같다면

ANIMAL_ID ANIMAL_TYPE DATETIME INTAKE_CONDITION NAME SEX_UPON_INTAKE
A399552 Dog 2013-10-14 15:38:00 Normal Jack Neutered Male
A379998 Dog 2013-10-23 11:42:00 Normal Disciple Intact Male
A370852 Dog 2013-11-03 15:04:00 Normal Katie Spayed Female
A403564 Dog 2013-11-18 17:03:00 Normal Anna Spayed Female

이 중 가장 보호소에 먼저 들어온 동물은 Jack입니다. 따라서 SQL문을 실행하면 다음과 같이 나와야 합니다.

NAME
Jack

※ 보호소에 가장 먼저 들어온 동물은 한 마리인 경우만 테스트 케이스로 주어집니다.

나만의 풀이 7

앞선 형태와 유사하지만, 이번엔 딱 1개만 추출하라 되어있다.
따라서 개수를 제한하는 명령을 추가로 넣어주면 된다.
구문 마지막에 LIMIT를 넣고 원하는 개수를 적어주면 된다.

SELECT NAME FROM ANIMAL_INS
ORDER BY DATETIME
LIMIT 1

+참고로 LIMIT문에서 숫자를 2개 쓰는 경우 파이썬의 range()문에서와 같은 효과를 지닌다.
가령 LIMIT 3, 5라고 하면, 4번째 레코드부터 5개를 연달아 추출한다는 의미이다.
(절대 3번째 레코드부터가 아님!)

오랜만에 SQL문을 다뤄보니 새롭기도 하다.
알고리즘 문제보단 쉬운 것 같다는 느낌이 든다. (신종 복선인가?)
실제 업계에서는 SQL 기반 데이터도 많이 다룬다고 한다.
따라서 데이터 분석을 위한 언어(파이썬, R 등..) 테스트에다 SQL이 추가로 첨가되는 경우가 많다.
아무튼 SQL문을 쓰는 문제들도 이렇게 하나씩 알아가면 좋겠다 생각한다.

728x90