[SQL] subquery 를 From 절에 쓸 때 주의할 점

Joey·2020년 8월 29일
3

SQL

목록 보기
1/1

문제 출처 바로가기 👉🏻

이 글에서 이야기하고 싶은 인사이트는 subquery를 From절에 쓸 때 주의할 점이기 때문에, 문제 설명은 skip!

문제의 코드

SELECT d.Name AS Department, e.Name AS Employee, e.Salary AS Salary
FROM( -- subquery 시작
    SELECT *
    ,DENSE_RANK() OVER (PARTITION BY d.name ORDER BY e.Salary DESC) as s_rank
    FROM Employee e
    INNER JOIN Department d ON e.DepartmentID = d.Id) AS sub
WHERE s_rank IN (1,2,3)코드를 입력하세요

주의할 점 1️⃣
문제코드의 세번째 줄처럼 테이블을 만드는 subquery에서 SELECT * 로 모든 컬럼을 가져오면 용량, 시간 면에서 좋은 코드가 아님. 구글 빅쿼리같이 쿼리가 추출한 데이터 양에 따라 비용산정하는 플랫폼을 쓸 경우 비용에서 어마어마한 차이를 가져올 수 있다!

주의할 점 2️⃣
subquery 내에서 두 테이블을 join 하고 있는데, 각각 테이블에 id, name 컬럼이 들어 있는 상태이다.
이때 아래의 두가지 방법으로 subquery에서 가져올 경우 오류가 발생한다.
1) select *
2) select e.id, d.id

왜냐하면, 사람은 subquery에서 꺼낸다음 e.id, d.id 로 구분지어서 써줘야지 라고 생각할 수 있지만 DBMS 실행 순서는 그렇지 않다.
우선 From 절에서 추출하는데에 중복을 발견했기 때문에 실행되지 않고 에러메시지를 뱉어낸다.

*에러 메시지: The column 'Id' was specified multiple times for 'sub'. (8156) (SQLExecDirectW)

[테이블 참고]
Table1. Employee

Table2. Department

올바른 코드

SELECT Department, Employee, Salary
FROM(
    SELECT d.Name AS Department, e.Name AS Employee, e.Salary AS Salary
    ,DENSE_RANK() OVER (PARTITION BY d.name ORDER BY e.Salary DESC) as s_rank
    FROM Employee e
    INNER JOIN Department d ON e.DepartmentID = d.Id) AS sub
WHERE s_rank IN (1,2,3)

-> 여기서 subquery 에서 d.Name, e.Name 을 출력하고 있는걸 볼 수 있는데, AS 로 구분지어주었기 때문에 에러가 발생하지 않고 있다.

From절에 Subquery 사용에 배운점

  1. 필요한 컬럼만 SELECT 하자!
  2. 중복된 컬럼명이 있을 경우 AS 로 구분지어서 사용하자!
profile
데이터 뿌시자

1개의 댓글

comment-user-thumbnail
2020년 9월 8일

안녕하세요, Subquery관련 주의사항 잘 읽었습니다.
질문 사항이 있어 댓글을 남깁니다. 주의할점 1에 말씀해주신 bigquery 비용은 측정해 볼 수 있는 방법이 있을까요? 빅쿼리를 사용할 때 얼마나 차이나는지 확인해보고 싶어서 질문드립니다.

답글 달기