[mysql] group by와 case문 함께 사용하기

kiki·2024년 9월 15일
0

프로그래머스

목록 보기
77/78

https://school.programmers.co.kr/learn/courses/30/lessons/276036
위 문제를 풀다가 난관에 봉착했다.

select case
    when 'Front End' in category then 'A'
    else NULL
    end as grade,
    id, email
from skill_of_d
group by id, email

개발자 별로 스킬을 확인해야하기에, group by를 사용해야하는데 그 안에서 등급 지정을 위해 case문을 써야했다. (대충 위와 같이 작성하고싶었음.)

근데 case문에 사용되는 컬럼(categroy)이 group by에 사용된 컬럼(id, email)이 아님.
그래서 집계함수를 써야하는 상황...!

with skill_of_d as (
    select *
    from developers
    join skillcodes on skill_code & code = code
)

select case
    when group_concat(category) like '%Front End%' and group_concat(name) like '%Python%' then 'A'
    when group_concat(name) like '%C#%' then 'B'
    when group_concat(category) like '%Front End%' then 'C'
    else NULL
    end as grade,
    id, email
from skill_of_d
group by id, email
having grade is not null
order by grade, id

그래서 위 쿼리처럼 group_concat 함수를 사용해 해결했다.

group_concat

group_concat은 그룹화된 결과의 특정 컬럼의 값들을 하나로 concat해주는 함수이다.

select id, group_concat(category) from skill_of_d group by id

이와 같이 작성하면 개발자별로 갖고있는 skill category를 전부 합쳐서 볼 수 있다.
'Front End,Back End'와 같은 결과를 얻을 수 있는 것!

여기서 주의할 점은 구분자를 따로 지정하지 않으면 쉼표(,)가 디폴트라는 것이다.
만약 구분자를 따로 지정하고싶다면,group_concat(category seperator '|')와 같이 지정해줄 수 있다.

근데 왜 HAVING에선 group by에 사용하지 않은 컬럼을 쓸 수 있지?

왜 having에선 그룹화 때 사용하지 않은 컬럼을 사용할 수 있나 잠깐 헷갈렸다.

위 쿼리대로라면, id와 email로 그룹화 해서 개발자 별로 하나의 grade를 할당 받으니 grade 또한 having 조건에서 사용할 수 있다.

즉, group by에 사용되진 않았지만 집계함수가 사용된 컬럼에 대해서는 having에서 사용할 수 있는 것이다.


<chat gpt 曰>

  • 집계 함수가 사용된 경우, GROUP BY에 없는 컬럼도 HAVING에서 사용할 수 있습니다.
  • 집계 함수가 없는 경우, GROUP BY에 포함되지 않은 컬럼은 HAVING에서 사용할 수 없습니다.

근데 having에서 select절의 alias를 사용할 수 있나?

having 다음 select가 실행되는데 안되는게 아닌가 싶었다.

chat gpt에 따르면,,, group by 후에 집계함수가 계산되고 having이 실행된다는데, 정확한 정보인지는 잘 모르겠다. 이건 좀 더 알아보고 추가하도록 하겠다.

결론

  • group by에 사용하지 않은 컬럼을 select 절에서 사용하기 위해선 집계함수를 써야함
  • having엔 집계함수를 사용한 컬럼 혹은 group by에 사용한 컬럼만 쓸 수 있다.
  • group_concat을 이용해 그룹화 된 값에 대해 문자열들을 쉼표로 concat할 수 있다.

0개의 댓글