[pro] SQL 고득점 kit 모음 1(SELECT, SUM/MAX/MIN, GROUP BY)

letsbebrave·2022년 3월 22일
0

codingtest

목록 보기
62/146
post-thumbnail

프로그래머스 SQL 고득점 kit

https://programmers.co.kr/learn/challenges

SQL 문제 풀 때 중요한 점

  • 무슨 데이터 컬럼이 있는지 확인
  • 테이블 간 구조 확인
  • 문제의 조건들 똑바로 읽고 주석으로 표시해두기 (마지막 정렬까지!)

쿼리문의 실행 순서

SELECT - 5순위 (필수)

FROM - 1순위 (필수)

WHERE - 2순위

GROUP BY - 3순위

HAVING - 4순위 // HAVING 은 GROUP BY가 적용된 이후에 실행됨

ORDER BY - 6순위 // ORDER BY는 모든 데이터들을 조회가 완료된 다음, 최후에 정렬함

SELECT, SUM, MAX, MIN

조건 포함하고 검색
WHERE 조건 = ''
SELECT ANIMAL_ID, NAME FROM ANIMAL_INS WHERE INTAKE_CONDITION = 'Sick' ORDER BY ANIMAL_ID ASC

제외하고 검색
WHERE 조건 != ''
SELECT ANIMAL_ID, NAME FROM ANIMAL_INS WHERE INTAKE_CONDITION != 'Aged' ORDER BY ANIMAL_ID ASC

상위 n개 레코드
LIMIT n
SELECT NAME FROM ANIMAL_INS ORDER BY DATETIME ASC LIMIT 1

중복제거, NULL 값이 아닌 것은 집계X
WHERE 조건 IS NOT NULL
COUNT(DISTINCT 조건)
SELECT COUNT(DISTINCT NAME) FROM ANIMAL_INS WHERE NAME IS NOT NULL

일단 WHERE 조건절로 NAME이 NULL이 아닌 데이터 중 DISTINCT로 중복을 제거하고 COUNT로 개수를 센다

GROUP BY

동물 종별 몇 마리인지 세기

SELECT
       ANIMAL_TYPE
     , COUNT(ANIMAL_ID) AS count -- 그룹화된 것들의 각각의 개수 구함
  FROM ANIMAL_INS
 GROUP BY ANIMAL_TYPE -- 먼저 ANIMAL_TYPE 같은 것 끼리 데이터 그룹화됨
 ORDER BY ANIMAL_TYPE ASC 
 -- ORDER BY는 모든 데이터들을 조회가 완료된 다음, 최후에 정렬함

동명 동물 수 찾기

먼저 NAME이 NULL이 아닌 조건
WHERE NAME IS NOT NULL
이름으로 그룹화
HAVING절에서 GROUP BY한 데이터에 대한 조건을 주고 받아오기 위해 NAME을 COUNT로 세주고 2 이상인 것만 받아옴
HAVING COUNT(NAME) >= 2
정렬은 이름 순

SELECT
       NAME
     , COUNT(NAME) as COUNT
  FROM ANIMAL_INS
 WHERE NAME is NOT NULL
 GROUP BY NAME
 HAVING COUNT(NAME) >= 2
 ORDER BY NAME

입양시각 구하기 (1)

처음에 짠 코드

SELECT
       HOUR(DATETIME)
  FROM ANIMAL_OUTS
 GROUP BY HOUR(DATETIME)
 HAVING HOUR(DATETIME) >= 9 and HOUR(DATETIME) < 20
 ORDER BY HOUR(DATETIME)

SQL 실행 중 오류가 발생하였습니다.
Unknown column 'DATETIME' in 'having clause'

HAVING을 걸 때는 순수한 column명을 그대로 써줘야 함!

  • HAVING 이후 조건을 거는 column은 추가적인 command가 가미되지 않은 순수한 column명을 그대로 써줘야 함
  • HAVING HOUR(DATETIME) => HAVING 별칭
  • HOUR(DATETIME)은 DATETIME에서 HOUR만 뽑아주는 COMMAND가 가미된 column
  • SELECT HOUR(DATETIME) as HOUR 처럼 별칭 선언해주고 HAVING절에서 해당 별칭 사용
SELECT
       HOUR(DATETIME) as HOUR
     , COUNT(HOUR(DATETIME)) as COUNT
     -- 이미 HOUR(DATETIME)으로 group화된 데이터를 가짐
     -- COUNT(DATETIME) as COUNT 해줘도 괜찮음
  FROM ANIMAL_OUTS
 GROUP BY HOUR(DATETIME)
 HAVING HOUR >= 9 and HOUR < 20 -- HOUR 별칭 컬럼 사용
 ORDER BY HOUR(DATETIME)

입양시각 구하기 (2)

SET 명령어를 사용해야 함! (사용자 정의 변수)
데이터베이스에 없는 시간을 만들어주기 위해 0부터 23시까지 먼저 테이블을 만들어줘야 한다.

사용자 정의 변수 by SET

변수 선언법

SET @변수명 = 변수값; -- 변수 선언, 값 대입
SELECT @변수이름; -- 변수 출력

SET 이외의 명령문에서는 =가 비교연산자로 취급되기 때문에 SELECT로 변수를 선언하고 값을 대입할 때는 :=를 사용!

예제 1

SET @VAR1 = 1;
SET @VAR2 = 2;

SELECT @VAR1; -- 결과 1
SELECT @VAR1 + @VAR2; -- 결과 2

예제2

SET @start = 15, @finish = 20;

SELECT * FROM EMPLOYEE
WHERE ID BETWEEN @start AND @finish;

입양시각 구하기 (2) 풀이

먼저, 현재 데이터베이스에는 없는 시간까지해서 0부터 23시까지를 만들기 by SET

SET @HOUR := -1;

SELECT (@HOUR := @HOUR + 1) AS HOUR
FROM ANIMAL_OUTS
WHERE @HOUR < 23;

0 ~ 23까지의 테이블이 완성됨
HOUR 변수에 HOUR + 1씩 대입해주면서 0부터 23일때까지 테이블이 완성됨

다음은 COUNT한 테이블을 만들어줘야 함
HOUR(DATETIME) 입양일의 시각과 HOUR변수가 같을 경우 하나씩 개수를 COUNT해줘야!
(SELECT COUNT(*) FROM ANIMAL_OUTS WHERE HOUR(DATETIME) = @HOUR) AS COUNT

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
profile
그게, 할 수 있다고 믿어야 해

0개의 댓글