MySQL 프로그래머스 | 언어별 개발자 분류하기 (GROUP_CONCAT, FIND_IN_SET 함수)

    728x90

     

    문제

    https://school.programmers.co.kr/learn/courses/30/lessons/276036

     

    프로그래머스

    코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

    programmers.co.kr

    • GRADE별 개발자 정보 조회.
    • GRADE 기준
      • A : Front End 스킬과 Python 스킬을 함께 가지고 있는 개발자
      • B : C# 스킬을 가진 개발자
      • C : 그 외의 Front End 개발자
    • GRADE가 존재하는 개발자의 GRADE, ID, EMAIL을 조회하는 SQL 문 작성
    • 결과는 GRADE와 ID 기준 오름차순 정렬

     

    테이블

    SKILLCODES
    DEVELOPERS

     

    풀이과정

    # DEVELOPER 테이블과 SKILLCODES 테이블 조인

    • DEVELOPER 테이블의 SKILL_CODE와
      SKILLCODES 테이블의 CODE를 비트연산자 & 를 사용해서 조인하면
      해당 SKILL_CODE에 포함되어 있는(해당 자릿수가 1인) 스킬들을 확인할 수 있음
    1
    2
    3
    4
    SELECT *
    FROM DEVELOPERS D
    JOIN SKILLCODES S ON D.SKILL_CODE & S.CODE
    ORDER BY ID
    cs

     

     

    # 다른 사람 풀이 (1)

    • GROUP_CONCAT 함수를 이용해 (ID와 EMAIL 별로) 스킬 이름과 카테고리를 구분자(,)로 묶음 >> skills, dev_skills
      • GROUP_CONCAT(컬럼명, ',', 컬럼명) :  스킬 이름과 카테고리를 , (콤마)로 연결함
    • FIND_IN_SET 함수를 이용해 위에서 GROUP_CONCAT으로 묶은 문자열 안에서 조건에 맞는 문자를 찾음. (매칭되는 문자가 있으면 0보다 클 것.) 문제에서 제시한 GRADE 조건에 따라서 A, B, C 등급 구분 >> grade_dev
      • FIND_IN_SET(str, str_list) : 콤마로 구분되어 있는 str_list에서 매칭되는 str 문자가 있는지 확인해줌.
        매칭되는 문자가 있는 경우, 해당 문자의 자리 번호를 반환하고, 없으면 0 반환.
      • 마지막에 GRADE와 ID로 정렬 조건 주면 끝!
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    SELECT GRADE, ID, EMAIL
    FROM(SELECT CASE 
                WHEN (FIND_IN_SET('Python', skills) > 0 AND FIND_IN_SET('Front End', skills) > 0) THEN 'A'
                WHEN (FIND_IN_SET('C#', skills) > 0) THEN 'B'
                WHEN (FIND_IN_SET('Front End', skills) > 0) THEN 'C'
                END AS GRADE,
                ID,
                EMAIL
         FROM (SELECT D.ID,
                      D.EMAIL,
                      GROUP_CONCAT(S.NAME, ',', S.CATEGORY) AS skills
               FROM DEVELOPERS D
               JOIN SKILLCODES S ON (D.SKILL_CODE & S.CODE) = S.CODE
               GROUP BY D.ID, D.EMAIL
               ) AS dev_skills
        ) AS grade_dev
    WHERE GRADE IS NOT NULL
    ORDER BY GRADE, ID;
    cs

     

    https://school.programmers.co.kr/questions/76142

     

    프로그래머스

    코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

    programmers.co.kr

     

     

    #  다른 사람 풀이 (2)

    1
    2
    3
    # A등급 (하단 정답 코드 일부 발췌)
    CASE WHEN SUM(CASE WHEN B.NAME='Python' THEN 3
                              WHEN B.CATEGORY = 'Front End' THEN 1 ELSE 0 END) > 3 THEN 'A'
    cs

     

    • A등급 : Front End 스킬과 Python 스킬을 함께 가지고 있는 개발자
      • 이 때 Front End 스킬을 가진 경우 1, 아니면 0을 반환함.
      • Python 스킬을 가진 경우 최소한 3 이라는 숫자를 부여해야 하고, 전체 SUM 값도 3 초과 (> 3)가 되게 해야 함.
        (3 이상의 임의의 숫자는 모두 가능)
        • 최소한 3이라는 숫자를 부여해야 하는 이유는,
          SKILLCODES 테이블에 카테고리가 Front End인 경우는 3가지(JavaScript, React, Vue)이기 때문.
        • A등급이 되기 위해서는 적어도 한 가지 이상의  Front End 스킬과 Python 스킬을 가지면 됨.
        • (예시) 만약 한 개발자가 Front End 세 가지 스킬을 모두 가지고 있는 경우에는 각각 1을 반환하게 되고,
          이 때 Python 스킬에도 1이라는 숫자를 부여하면 SUM값은 앞서 Front End 스킬 3개 반환값(3)과 Python 스킬 반환값(1)을 합한 4가 되므로 3 초과 조건을 통과해 A등급이 부여됨.
        • 하지만!! 만약 한 개발자가 Front End 스킬 중 한 개의 스킬만 가지고 있으면 SUM 값은 1이 되고, 
          여기에 Python 스킬에도 1이라는 숫자를 부여하면 SUM값은 2가 되고, 3이 초과 조건에 부합하지 않아 (문제에서 요구한 A등급 기준에 적합함에도) A등급을 받을 수 없게 됨.
        • 이런 경우까지 모두 고려해봤을 때, Python 스킬에 적어도 3이라는 숫자를 부여함으로써 Python 스킬과 더불어 Front End 스킬 중 어느 하나라도 보유한 사람이라면 A등급이 나오게 해야 함.
        • 그 결과 Python 스킬 반환값은 적어도 3이어야 하고, A등급 조건도 3 초과여야 함.

    • B등급 : C# 스킬을 가진 개발자  
      • C# 스킬을 가진 경우 1, 그렇지 않은 경우 0을 반환
    • C등급 : 그 외의 Front End 개발자
      • Front End 스킬을 가진 경우 1, 그렇지 않은 경우 0을 반환
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    SELECT A.GRADE ,A.ID ,A.EMAIL
    FROM(
    SELECT A.ID,
           CASE WHEN SUM(CASE WHEN B.NAME='Python' THEN 3
                              WHEN B.CATEGORY = 'Front End' THEN 1 ELSE 0 END) > 3 THEN 'A'
                WHEN SUM(CASE WHEN B.NAME='C#' THEN 1 ELSE 0 END) > 0 THEN 'B'
                WHEN SUM(CASE WHEN B.CATEGORY = 'Front End' THEN 1 ELSE 0 END) > 0 THEN 'C'
                ELSE NULL END AS GRADE,
                MIN(A.EMAIL) AS EMAIL
    FROM DEVELOPERS A
    INNER JOIN SKILLCODES B ON A.SKILL_CODE & B.CODE = B.CODE
    GROUP BY A.ID
    ) A
    WHERE A.GRADE IS NOT NULL
    ORDER BY A.GRADE, A.ID;
    cs

     

    https://school.programmers.co.kr/questions/79636

     

    프로그래머스

    코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

    programmers.co.kr

     

    728x90

    댓글