Today I Learned/SQL

subquery 를 From 절에 쓸 때 주의할 점

하나719 2020. 8. 31. 17:35
반응형

문제 출처 바로가기 👉

이 글에서 이야기하고 싶은 인사이트는 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)

 

 

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 로 구분지어서 사용하자!

반응형