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

데잇걸즈4기_박유빈님의 프로필 이미지

작성한 질문수

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

WHERE절 ALIAS와 서브쿼리 관련 질문 드립니다

20.09.08 13:47 작성

·

4.2K

3

안녕하세요.

WHERE절 ALIAS에 관한 질문과 서브쿼리 관련 질문 드립니다.

1.

-문제: 185. Department Top Three Salaries (LeetCode)

-질문: 다른 절에 적어 놓은 ALIAS를 WHERE절에서 끌어와 쓸 수 없다고 알고있는데, 아래 정답에서 dr은 왜 돌아가는지 궁금합니다.

다른 사람에게 질문했을 때,  WHERE절에서 ALIAAS를 '만들 수 없다'는 말일거란 답변을 얻었는데요.

WHERE절에서 ALIAS를 만들수도 없지만, 가져다 쓸수도 없는 거 아닌가요?ㅎㅎ

-정답:

--------------------------------------------------------------------------------------------------------------

2.

-문제: 196. Delete Duplicate Emails (LeetCode)

-질문: 서브쿼리에 대한 이해가 부족해서 질문합니다. 오답처럼 서브쿼리를 하나만 쓰면 왜 안 되는지 궁금합니다.

-정답:

DELETE

FROM Person

WHERE Id NOT IN

SELECT sub.min_id

FROM ( 

SELECT Email, MIN(Id) AS min_id

FROM Person GROUP BY Email

) sub)

-오답:

DELETE

FROM person

WHERE id NOT IN (

SELECT MIN(id) AS min_id

FROM person

GROUP BY email )

--------------------------------------------------------------------------------------------------------------

3.

-문제: 해커랭크 Top Earners

-질문: 아래쿼리에서 왜 에러가 나는지, MAX와 관련이 있는건지 궁금합니다.

-오답:

SELECT employee_id,
       name,
       MAX(months * salary) AS total_earnings
FROM employee

추가적으로,

(1)GROUP BY에서 alias할 수 없고, 사칙연산 할 수 없다.

(2)HAVING에서는 alias는 할수 없고. 사칙연산 할 수 있다.고 알고 있는데요. 맞나요?

어떤 블로그에서 GROUP BY에서 ALIAS을 할 수 없다고하는데, 해커랭크 Top Earners 문제풀이에서는 되는 것 같아 질문드립니다. 

질문이 많은데.. 늘 친절하게 답변해주셔서 감사합니다ㅜㅜ!

답변 2

2

송혜정님의 프로필 이미지
송혜정
지식공유자

2020. 09. 08. 22:09

안녕하세요 유빈님, 답변 드립니다.

1. 이 부분은 서브 쿼리 강의 4:08 이후 부분을 복습하시면서 서브쿼리 개념을 다시 정리하시는 것을 추천드립니다.
dr이 SELECT절에 사용된 alias라면 WHERE 절에서 사용할 수 없지만, dr은 FROM절 서브쿼리 t를 통해 생성된 테이블의 컬럼 이기 때문에 WHERE절에서 사용이 가능합니다. 즉, 질문 주신 WHERE절의 dr은 alias가 아니며, FROM절 테이블의 컬럼 이기에 사용 가능한 것입니다.
또한, dense_rank()는 윈도우를 만들지 않은 상태로, WHERE DENSE_RANK() <= 3 과 같은 형태로 사용하실 수 없으며, WHERE절에는 윈도우 함수를 사용하실 수 없습니다. (참고: [learnsql.com] Why Window Functions Are Not Allowed in WHERE Clauses )

2. 과거에 동일한 내용의 질문이 있어 당시 답변을 인용합니다. ( 참고: 해당 질문 내용 )
"

MySQL은 DELETE문의 하위 절에서 동일한 테이블을 사용하지 못하게 하고 있습니다. 그래서 'NOT IN'절에서 새 테이블이 필요하기 때문에 중간에 select 문을 넣어 새롭게 만들어줘야만 사용할 수 있습니다. 

https://dev.mysql.com/doc/refman/5.6/en/delete.html

https://dev.mysql.com/doc/refman/8.0/en/subquery-restrictions.html

이 링크를 참고하시면 더 많은 도움이 될 것입니다. :)
"

3. Top Earners 문제는 중급 강의에서 다룬 문제로 보이는데요, 각 강의에서 다룬 내용에 대한 질문 남겨주시면 감사하겠습니다.
간단히 답변드리면 질문 주신 2 내용은 맞으나 1 내용는 틀립니다. GROUP BY 에서도 SELECT에 사용한 alias를 사용할 수 있으며, [mysqltutorial.org] MySQL Alias 문서에서 아래 내용 확인 부탁드립니다.
" The following statement selects the orders whose total amount are greater than 60000. It uses column aliases in GROUP BY and HAVING clauses. "
참고로, 모르는 내용은 공식 문서를 참고하는 것이 가장 좋기 때문에 영어로 검색하시는 것을 추천드립니다.

충분한 답변이 되었길 바라며, 추가 질문 있으시다면 남겨주세요 :)

0

데잇걸즈4기_박유빈님의 프로필 이미지

2020. 09. 10. 15:33

많은 질문에 꼼꼼히 답변해주셔서 감사합니다:)

설명해주신 내용과 사이트를 읽고 아래처럼 이해했는데, 혹시 잘못 이해한 부분이 있을까요?

--------------------------------------------------------------------------

[ALIAS에 관해 이해한 내용]

ALIAS는 컬럼 ALIAS와 테이블 ALIAS, 2종류가 있다. 

컬럼 ALIAS는 주로 SELECT절에서 사용된다.

-GROUP BY, HAVING, ORDER BY절에서 사용할 수 있다

-WHERE절에서 사용할 수 없다

테이블 ALIAS는 주로 FROM절 서브쿼리나 JOIN할 때 사용된다.

-(질문 내용에 있는) dr은 FROM절 서브쿼리에서 컬럼 ALIAS를 준 것은 맞다. 그러나 WHERE절에서 dr을 불러온 것은, 컬럼 ALIAS를 불러온 것이 아니라, 서브쿼리 테이블의 컬럼 자체를 불러온 것이므로, 사용 가능하다. 

-----------------------------------------------------------------------------------

추가로 사이트를 읽다 더 궁금한 점이 생겨서 질문 드립니다!

[질문: WHERE절에서 ALIAS를 못 쓰는 이유]

WHERE절에서 ALIAS 못 쓰는 이유는 MYSQL에서 WHERE절 처리할 시점에는, SELECT절에서 정한 컬럼 값이 아직 계산이 안 됐기 때문입니다. (The reason is that when MySQL evaluates the WHERE clause, the values of columns specified in the SELECT clause is not be evaluated yet.)

그렇다면, 마찬가지로 SELECT절 실행 전에 처리하는 GROUP BY랑 HAVING에서도 ALIAS를 쓸 수 없어야하는거 아닌가..하는 생각이 들었습니다. 왜 WHERE절에서만 안되는지 궁금합니다! 

*제가 이해한 쿼리 실행 순서: FROM > WHERE > GROUP BY > HAVING > SELECT > ORDER BY

---------------------------------------------------------------------------------------------

그리고 3번 질문 해커랭크 Top Earners은 SQL중급/고급 강의에서 둘 다에서 다루는 문제 같은데요!

말씀해주신대로 MAX 활용 풀이에 관한  질문은 중급으로 옮겼습니다ㅎㅎ

같은 문제를 서브쿼리 활용해서 풀어보다(고급> 서브쿼리 해커랭크문제풀이 5:30부터) 궁금한 점이 생겨서 여기에 질문드립니다. 

HAVING 활용해서 풀어봤을 때,  COUNT(employee_id)를 하면 에러가 나는 이유가 뭘까요?

-정답

SELECT salary * months AS earnings

              , COUNT(*)

FROM employee

GROUP BY earnings

HAVING earnings = (SELECT MAX(salary*months) FROM employee)

-오답

ERROR 1054 (42S22) at line 1: Unknown column 'months' in 'having clause'

SELECT months * salary AS earnings

               , COUNT(employee_id)

FROM Employee

GROUP BY earnings

HAVING months * salary = (SELECT MAX(months*salary) FROM Employee)

-----------------------------------------------------------------------------

답변주신 덕분에 sql을 조금씩 더 이해하고 있습니다.  감사합니다ㅎㅎ!!