자신에게 친절할 것 :)

Data Science/MySQL

[HackerRank sql] where절과 from절 서브쿼리 차이

Tashapark 2025. 1. 28. 17:51
728x90
반응형

Contest Leaderboard

- 나름 거의 다 했는데..

- 0일 때 제외하는 조건을.. 고민하다가 틀렸다. 

- 검색해서 not in으로 해볼려고 했는데.. 하면서도 뭔가 이상하더라. ㅎ

 

수정 전

select h.hacker_id, h.name, sum(s.score)
from hackers
join submissions s using(hacker_id)
group by h.hacker_id, h.name
having s.score = (select max(s1.score)
                 from submissions s1
                 where s1.challenge_id = s.challenge_id 
                 and not in (s1.score = 0) ) -- 여기가 계속 긴가민가 했었다...ㅎ
order by s.score desc, h.hacker_id;

 

- 코드가 이상한듯.. 계산이 제대로 안되네..

 

수정 후1) gpt가 준 코드인데 이것도 안돼.. 

- 값은 나오는데 어디서 에러가 뜨는 지를 모르겠음. 

- 일단 having이 아니라 전체 코드에서 조건 where절을 줘야 하는 것은 알겠는데.. 

select h.hacker_id, h.name, sum(s.score)
from hackers h
join submissions s using(hacker_id)
where s.score > 0 
and s.score = (select max(s1.score)
                 from submissions s1
                 where s1.challenge_id = s.challenge_id 
                and s1.hacker_id = s.hacker_id
                  )
group by h.hacker_id, h.name
order by sum(s.score) desc, h.hacker_id asc;

 

수정 후 2) 지피티 + 디스커션 

- 디스커션을 확인해 보니깐 거의  인라인 뷰(Inline View) 였고, 나는 이전 문제를 거의 중첩 서브쿼리( Nested Subquery ) 로 풀었기 때문에 그렇게 했는데 그게 아니라 인라인 뷰로 해야 한다. 

- 값의 차이는 명백하게 모르겠으나, 실행 순서  때문으로 여겨지는 데, sql에서 from -> where 절로 가는 순서상 

중첩 쿼리로 하면 전부 다 순회해야 해서 그런 것으로 생각된다...  아마도..? 근데 그게 핵심이 아닌 것 같기도 하고.. 

- challenge_id를 셀렉하지 않아서 그런 것인지 명백하게 안되는 이유를 사실은 잘 모르겠다..

- 인라인 뷰의 경우에는 alias를 반드시 표기해 줘야만 한다. 

 

==> 1) 쿼리 성능 문제. 2) score의 모호성

- 1)  where절이 from 이후에 적용되기 때문에 로우가 많아질 수록 여러번 계산해야 하는 문제가 있음. 성능이 nested면 너무 떨어짐. 

- 2)  score가 중복이 되는 경우 max를 찾기가 모호하다고 함.. 

   - 그래서 아마도 challenge_id도 동시에 group by를 하는 듯. 2번에 나눠서 생각할 줄 알아야 함. 

 

 

select h.hacker_id, h.name, sum(s.max_s) as total_s
from hackers h
join ( -- 인라인 뷰로 해야 score가 중복된 경우에도 문제가 제대로 해결됨.
    select hacker_id, challenge_id, max(score) as max_s -- 챌린지 아이디가 셀렉트로 들어가야 함. 
    from submissions
    where score > 0 
    group by hacker_id, challenge_id -- 챌린지 아이디로 그룹화를 해야함. 아니면 해커 아이디당 max 1개만 나옴
) s using(hacker_id)
group by h.hacker_id, h.name
order by total_s desc, h.hacker_id asc;

 

 

728x90
반응형