[데이터베이스] 쿼리의 구성요소 실행 순서

단순한 궁금증에서 시작되, 정리해놓으면 좋을 거 같아 짬을 내어 글을 쓰게 되었다. 

데이터베이스 시험공부 문제를 풀며 감 익히고 있는데

 

 

Suppose that we have a relation marks(ID, sore) and we wish to assign grades to students based on the sore as follows: grade F if score < 40, grade C if 40 if score < 60, grade B if 60 if score < 80, and grade A if 80 f score. Write SQL queries to do the following:

 

문제 출처 : Database System Concepts (Seventh Edition)

 

Find the number of students with eah grade.

 

문제 해석 : 각 학생의 점수(score)를 기준으로 학점(grade)을 계산해서 출력해라.

 

즉, 문제에서 요구하는 것은

각 학생들마다 받은 점수를 40점 미만은 F, 60점 미만은 C .... 80점 이상은 A 로 출력하라는 것이다. 

 

처음 내가 작성한 쿼리문은 

select case 
        when score < 40 then 'F'
        when score < 60 then 'C'
        when score < 80 then 'B'
        else 'A'
    end as grade, count(distinct ID)
from works
group by grade;

였는데, 

해당 부분을 gpt에게 물어보니 오류라 한다. 

group by grade에서 문제가 일어난다.

따라서 옳게 고치면 with 구문을 써 1회용 뷰를 만들어 사용한다. 

with grades as
( select ID,
		case
            when score < 40 then 'F'
            when score < 60 then 'C'
            when score < 80 then 'B'
            else 'A'
		end as grade
		from marks
)
select grade, count(ID)
from grades
group by grade;

with를 쓰지 않는 방안은 아래와 같이, 

select에서 실행했던 case구문을 group by에서도 반복하는 것이다. 

직관적으로 느껴지겠지만, 쓸데없이 쿼리문이 길어지고, 앞서 제시한 with로 간단하게 표현할 수 있기에 너무 비효율적이다. 

SELECT 
  CASE
    WHEN score < 40 THEN 'F'
    WHEN score < 60 THEN 'C'
    WHEN score < 80 THEN 'B'
    ELSE 'A'
  END AS grade,
  COUNT(ID)
FROM marks
GROUP BY 
  CASE
    WHEN score < 40 THEN 'F'
    WHEN score < 60 THEN 'C'
    WHEN score < 80 THEN 'B'
    ELSE 'A'
  END;
❓왜?
sql의 실행 순서를 보면

from -> where -> group by -> select -> order by
순인데, 

내가 쓴 쿼리문에서는 select전에 group by grade를 실행하기 때문에
select에서 정의한 grade를 못 찾아 오류가 나는 것이다. 

🤔 설명은 간결하지만, 문득 왜 이런 순서로 쿼리가 실행되어야 하는지 의문이 들었다. 
select 에서 rename operator(as)로 정의한 명사를 group by에서 쓸 수 없도록 한 이유가 무엇일까?

📌 다시 말하면, 왜 위와 같은 실행 순서를 선택했을까?

SELECT는 뷰(View)를 만드는 작업이고, GROUP BY는 뷰를 만들기 전에 어떤 기준으로 뭉칠지를 미리 정하는 설계도를 그리는 것이다. 
설계도를 그릴 때 뷰가 완성되기를 기다릴 순 없으니 (group by -> select)순서를 따르는데, 

 

하지만, 일부 DB에서는 허용한다고 한다. MYSQL에서는 편의성을 위한 비표준 확장을 위해 허용한다. 

하지만 ANSI SQL기준으로는 권장되지 않는다. 

 

시험기간이라 더 못파겠다. 시험 끝나고 논리적인 이유 말고 다른 이유와 mysql에서 비표준 확장을 허용한 이유 관련해서 바로 좀 더 찾아봐야지.