✏️ STUDY etc./Code Kata
[D+23][SQL 코드카타 #1] 입양 시각 구하기(2) - SET문 변수 설정, ROW_NUMBER() OVER()
김숮엉
2024. 5. 30. 11:44
🚨코드카타 슬럼프에 빠지게 만든 65-75번 문제 구간🚨
그중 73번 문제. 입양 시각 구하기(2)을 통해 새로운 방식을 알게 되어 TIL로 기록해 보겠습니다.
처음에는 CASE WHEN 구문을 사용하여 0 ~ 24시에 해당하는 입양 건을 카운트하려고 했는데요.
쿼리가 너무 길어지고 비효율적이어서 '어.. 이게 아닌데..?' 싶더라구요.
그래서 다른 분들이 활용하신 SET문과 ROW_NUMBER()을 참고해서 풀었습니다.
1. SET문 변수 설정을 활용한 풀이
SET @HOUR = -1; # 변수 선언 및 HOUR 초기 값 세팅
SELECT @HOUR := @HOUR+1 AS `HOUR`,
(SELECT COUNT(*)
FROM ANIMAL_OUTS
WHERE @HOUR = HOUR(DATETIME)) AS `COUNT`# 변수에 해당하는 데이터 카운트
FROM ANIMAL_OUTS
WHERE @HOUR < 23; # 0시부터 23시까지 돌아갈 수 있도록 조건 할당
✅ 쿼리 풀이
- @HOUR라는 변수를 선언해 주고, SELECT문에 지정하여 @HOUR 값이 23이 될 때까지 반복
- 스칼라 서브쿼리를 활용해서 @HOUR 값과 HOUR(DATETIME) 값이 같은 데이터를 카운트하여 반환
✅ 간단하게 SET 개념 짚고 넘어가기
SET은 변수를 선언하거나 값을 할당할 때 사용합니다. 즉, SET은 말 그대로 변수를 세팅하는 것이에요!
SELECT나 조건 및 반복문에 활용할 수도 있고, DB 로직을 구현할 수도 있다고 해요.
- @를 활용해서 사용자 정의 변수를 할당 및 식별해요. SET의 변수명 앞에는 꼭 @를 붙여야 함.
- SET문의 변수 선언이 끝나면 꼭 ;(세미 콜론)으로 쿼리를 종결해야 해요. 그래야 각각 독립된 명령으로 인식하고 순차적으로 실행합니다. 만약 종결하지 않고, SELECT문을 사용하면 오류 납니다.
- SET에서 할당한 변수의 값을 변경할 때는 := 로 작성해줘야 합니다. 비교연산자(=)와 구분하기 위함!
2. 윈도우 함수 ROW_NUMBER()를 활용한 풀이
SELECT HOUR, COUNT(DATETIME) AS COUNT
FROM (SELECT (ROW_NUMBER() OVER() -1) AS HOUR
FROM ANIMAL_OUTS
LIMIT 24) AS A # 0~23까지의 숫자를 만들고 HOUR로 지정.
LEFT JOIN ANIMAL_OUTS B ON A.HOUR = HOUR(B.DATETIME)
GROUP BY HOUR
ORDER BY HOUR;
✅ 쿼리 풀이
- 윈도우 함수인 (ROW_NUMBER() OVER() -1)와 LIMIT을 활용해서 0~23 값을 가진 테이블 생성. -1을 하지 않을 경우 테이블이 1부터 시작되기 때문에 꼭 -1을 작성해줘야 함.
- LEFT JOIN을 통해 기존 테이블과 병합. 여기서 일반 JOIN을 사용하게 될 경우 HOUR(B.DATETIME)에 없는 A.HOUR는 생략되기 때문에 꼭 LEFT JOIN을 활용해야 원하는 결과 값을 얻을 수 있음.
- HOUR를 기준으로 데이터를 그룹화하여 데이터를 집계(COUNT())해줌. 만약 COUNT(*)로 작성하면 NULL값까지 세기 때문에, 꼭 별도의 칼럼을 지정해줘야 함!
✅ 반드시 알아야 할 포인트.
- ROW_NUMBER() OVER()는 행의 번호를 순차적으로 반환하는 윈도우 함수예요. 첫 행은 1부터 시작해요. 참고로, RANK()와 비슷하지만 값이 같더라도 순차적으로 고유한 번호를 매긴다는 점이 달라요.
(*RANK는 공동순위 인정. 값이 동일할 경우 1 > 1 > 3로 번호가 매겨짐.) - 기본 구조는 ROW_NUMBER() OVER(PARTITION BY 칼럼명 ORDER BY 칼럼명) 입니다. 위 쿼리처럼 다른 파티션과 오더 바이를 생략해도 실행됩니다. 파티션 파이에는 그룹의 기준이 될 칼럼이, 오더 바이에는 정렬하여 번호를 매길 칼럼이 들어가 됩니다.
[ 2024. 5. 30 Today I Learned ] 저를 SQL 슬럼프에 빠지게 한 문제의 구간을 지나고 있습니다..! 한 문제를 푸는데도 여러 풀이를 참고하고, 구글링 하면서 공부를 하게 되더라고요. 이전에 온라인 강의에서는 배우지 못했던 활용법을 알게 돼서 좋지만, 이런 풀이법을 제 스스로 아직 잘 짜지 못하는 것 같아서 부족함을 많이 느낍니다. 아직 코드카타 마의 구간이 남았는데, 또 새롭게 알게 되거나 풀이를 남기고 싶은 문제가 있다면 오늘처럼 제대로 짚고 가야겠습니다. 파이팅🍀