인프런 커뮤니티 질문&답변

Jeong K님의 프로필 이미지
Jeong K

작성한 질문수

[백문이불여일타] 데이터 분석을 위한 중급 SQL

강의 수강을 위한 준비 (1) - 해커랭크, w3school(기초반과 동일)

top earners 문제 having 을 이용해서 풀 수 없을까요

해결된 질문

작성

·

235

3

안녕하세요 group by를 이용해서 풀어주셨는데,

select months*salary as earnings, 

      count(name)

from Employee

Group by earnings

Having earnings=max(earnings)

이렇게 마지막에 having으로 조건을 걸어서 도출해보려 했더니 having을 넣지 않았을 때와 똑같은 결과값이 나오더라고요. 이 코드가 시행되지 않는 이유를 알 수 있을까요? 

그리고  한 가지 더 질문은  select에서 months와 salary를 이용해 earnings라고 새로 정의했는데요

select months*salary as earnings, max(earnings)

from Employee

라고 하면 Unknown column 'earnings' in 'field list'

라는 오류가 뜨더라고요, select에서 바로 앞에 정의한 변수는 다음 변수로 사용이 불가능한거 같은데 group by에서는 어떻게 바로 쓸 수 있는지 작동 순서가 혼란스러워서 이 부분에 대해서 설명해주실 수 있을까요? 

답변 3

2

윤선미님의 프로필 이미지
윤선미
지식공유자

안녕하세요. 비슷한 질문을 한 stackoverflow 링크를 첨부해요. 타래를 쭉 읽어보시면 도움이 될 것 같습니다. 참 명확하게 답변하기 어려우면서도, 좋은 질문을 하셨어요.

SQL은 선언형 언어(declarative language)로 '어떤 방법'으로 할 것인지를 기술하는 명령형 언어들과 달리 '무엇을' 할 것인지에 중점을 주고 있어요. 그래서 많은 분들이 실행 순서라던지, 내부의 동작 원리에 대해서 많이 궁금해하시는 것 같아요. 하지만 명확하게 대답을 해 드릴 수는 없습니다. DB 마다 다르기 때문이에요. MySQL, Oracle 등 많은 DB 들이 각각의 최적화 방법들을 가지고 있고, 따라서 똑같은 쿼리를 작성한다 하더라도 그 내부 실행 방식은 모두 다를 수 있습니다.

여기에서 SELECT 에서 사용한 Alias 가 같은 SELECT 구문에서 동작하지 않는 것은 DB의 최적화 방식 때문에, earnings 라고 정해준 Alias 에 대한 정보를 MAX(earnings) 를 계산할 때에 가지고 있지 않았다.. 정도로 생각해 볼 수 있겠네요.

간단하게는 SELECT 에서 정한 Alias는 같은 SELECT 구문 안에서는 사용할 수 없고, GROUP BY, HAVING, ORDER BY 에서 사용할 수 있다고 이해하시면 좋을 것 같습니다. 또는 subquery(쿼리 안의 쿼리)를 사용해 볼 수도 있을텐데요. 서브쿼리와 관련한 내용은 고급반에서 자세하게 다뤄보도록 하겠습니다. 지금 알고 싶으시다면 `MySQL 서브쿼리` 또는 `SQL 서브쿼리` 등으로 검색해보시면 인터넷에 내용들이 많으니까 공부해보실 수 있을 것 같아요 :)

좋은 질문 감사합니다.

https://stackoverflow.com/questions/34955911/why-cant-i-use-column-aliases-in-the-next-select-expression

https://stackoverflow.com/questions/4596467/order-of-execution-of-the-sql-query

1

윤선미님의 프로필 이미지
윤선미
지식공유자

첫 번째 질문은, GROUP BY에서 그룹의 기준으로 들어간 컬럼은 집계의 대상이 될 수 없습니다.

SELECT와 GROUP BY에서 earnings를 그룹을 만드는 기준으로 사용하셨기 때문에, MAX() 라는 집계 함수를 사용할 수 없다고 생각하시면 좋을 것 같아요. 대신 아래와 같이 subquery를 이용해서 Jeong K 님과 비슷하게 풀어볼 수 있습니다.

SELECT months*salary AS earnings, COUNT(name)
FROM Employee
GROUP BY earnings
HAVING earnings = (SELECT MAX(months*salary) FROM employee)

0

Jeong K님의 프로필 이미지
Jeong K
질문자

그렇군요 이해되었습니다. 첨부해주신 링크도 도움이 되었어요 감사합니다. 

Jeong K님의 프로필 이미지
Jeong K

작성한 질문수

질문하기