들어가며
코딩테스트를 준비하면서 SQL 1문제를 위해 프로그래머스에서 SQL 문제를 풀고 있었다.
SELECT 절에서 Lv3 까지는 그럭저럭 풀만했지만 Lv4 부터는 기존에 알고 있던 지식으로는 도저히 풀 수가 없었다.
SQL 작성에 대한 기본이 아직 약한 느낌이다.
그래도 AI한테 적절한 난이도의 문제를 만들어보라고 시키고, 그 문제를 풀고 바로 피드백을 받는 방식으로 연습하니까 Lv4~5 까지 실력이 향상된 것 같다.
이번 기회에 AI한테 SQL을 작성하는 마인드셋이나 쿼리를 작성할 때 생각해야 할 순서에 대해 물어보았고, 이를 기록하려고 한다.
SQL 작성의 5단계
SQL을 작성할 때 헷갈리는 이유가, 쿼리를 작성하는 순서와 DB 엔진이 실제로 쿼리를 실행하는 순서가 다르기 때문이다.
우리가 쿼리를 작성할 때 SELECT > FROM > WHERE > ... 이렇게 하향식으로 작성할 수도 있고, WHERE > ORDER BY > ... 처럼 작성하고 싶은 것부터 작성할 수 있다.
하지만 실제로 DB 엔진이 쿼리를 실행하는 순서는 FROM > WHERE > GROUP BY > HAVING > SELECT > ORDER BY 이다.
따라서 쿼리를 짤 때는 반드시 DB가 실제로 실행하는 순서대로 접근해야 수월하다.
1단계: FROM & JOIN
가장 먼저 FROM 절이다.
내가 필요로 하는 데이터를 어느 테이블에서 가져올 것인지 먼저 생각해야 한다.
이때 여러 테이블을 한 번에 묶기 위해선 JOIN 이나 LEFT JOIN을 고려한다.
Java의 Stream으로 비유하면
data.stream()와 같다.
2단계: WHERE
두 번째로 WHERE 절이다.
1단계에서 테이블을 세팅했다면, 그 다음으로는 내가 원하는 조건만 필터링한다.
여기서 불필요한 데이터를 최대한 쳐내야 쿼리 성능이 좋아진다.
Java의 Stream으로 비유하면
data.stream().filter()와 같다.
3단계: GROUP BY & HAVING
세 번째로 GROUP BY와 HAVING이다.
2단계에서 원하는 조건의 데이터만 필터링 했다면, 그 데이터들을 어떤 기준으로 묶을 것인지를 생각한다.
GROUP BY에 명시한 칼럼을 기준으로 하나의 그룹을 만든다. 따라서 개별 행의 데이터는 사라진다.
HAVING은 그룹핑 한 결과에서 또 다시 조건을 걸어 불필요한 데이터를 쳐내는 것이다.
Java의 Stream으로 비유하면
data.stream().filter().groupingBy().filter()와 같다.
4단계: SELECT & Window Function
4단계로 SELECT와 Window Function 이다.
Java로 비유하면 결과를 저장할 DTO를 만든다고 생각할 수 있다.
1단계부터 3단계까지 가공한 데이터들을 가지고, 내가 보고 싶은 결과를 조회하면 된다.
5단계: ORDER BY & LIMIT
마지막으로 ORDER BY와 LIMIT이다.
SELECT 절까지 완성한 결과 테이블을 가지고, 특정 기준으로 정렬하고 상위 n개를 잘라서 최종 결과 테이블을 완성한다.
Java로 비유하면
data.stream().filter().groupingBy().filter().sorted().limit(3)과 같다.
서브쿼리가 2 Depth 이상 깊어질 때는 WITH 절로 뺀다.
서브 쿼리가 2 Depth 이상되면 코드를 파악하고 수정하기 어렵다.
유지보수를 위해 변수와 메서드로 추출하는 것처럼 하나의 서브 쿼리는 WITH 절로 빼는 것이 정신 건강에 좋다.