SQL/프로그래머스

프로그래머스 | SQL 스터디 15 (SUBSTIRNG)

kimmalgu 2024. 9. 17. 15:32

    SELECT

    가장 큰 물고리 10마리 구하기(Lv1)

    문제 설명

    문제

    풀이

    SELECT로 ID, LENGTH를 조회

     

    ORDER BY에서 LENGTH 내림차순, ID 오름차순 정렬

     

    LIMIT 10으로 상위 10마리 출력

    SELECT ID, LENGTH
    FROM FISH_INFO
    ORDER BY LENGTH DESC, ID ASC
    LIMIT 10;

     


    특정 물고리를 잡은 총 수 구하기(Lv2)

    문제 설명

    문제

    풀이

    SELECT로 COUNT로 FISH_COUNT를 조회

     

    JOIN으로 공통 컬럼인 FISH_TYPE으로 두 테이블을 연결 

     

    WHERE에서 BASS, SNAPPER라는 FISH_NAME을 가진 것으로 제한

    SELECT COUNT(*) FISH_COUNT
    FROM FISH_INFO I
    JOIN FISH_NAME_INFO N ON N.FISH_TYPE = I.FISH_TYPE
    WHERE N.FISH_NAME IN ('BASS','SNAPPER');

     

     

    GROUP BY

    연간 평가점수에 해당하는 평가등급 및 성과금 조회하기 (Lv4)

    문제 설명

    문제

     

    풀이

    # 맨 처음 작성했던 올바르지 않은 쿼리문
    SELECT E.EMP_NO, E.EMP_NAME, 
        CASE
            WHEN AVG(SCORE) >= 96 THEN 'S'
            WHEN AVG(SCORE) >= 90 THEN 'A'
            WHEN AVG(SCORE) >= 80 THEN 'B'
            ELSE 'C'
        END AS GRADE,
        CASE
            WHEN GRADE = 'S' THEN SAL*0.2
            WHEN GRADE = 'A' THEN SAL*0.15
            WHEN GRADE = 'B' THEN SAL*0.1
            WHEN GRADE = 'C' THEN SAL*0
        END BONUS    
    FROM HR_EMPLOYEES E
    JOIN HR_GRADE G ON G.EMP_NO = E.EMP_NO
    GROUP BY E.EMP_NO
    ORDER BY E.EMP_NO;

    여기서의 문제점은

     

    • 1. CASE 문에서 사용된 GRADE 컬럼의 참조 문제:
      • GRADE는 CASE 문에서 생성된 *별칭(Alias)*이며, SQL에서는 SELECT 절에서 생성된 별칭을 다른 SELECT 절 내에서 직접 참조할 수 없습니다. 따라서 두 번째 CASE 문에서 GRADE를 직접 사용하는 것은 올바르지 않습니다. → WITH을 이용하여 GRADE는 빼는 것으로 결정!
    • 2. GROUP BY 절 문제:
      • AVG(SCORE)를 사용하는데, 이는 집계 함수이기 때문에, GROUP BY 절에 다른 컬럼들이 모두 포함되어 있어야 합니다. GRADE는 집계 함수에서 계산된 값이므로, GROUP BY로 지정할 수 없습니다. 대신 필요한 모든 컬럼을 명시해야 합니다.  → GROUP BY에 있는 칼럼들을 모두 포함시키기!

     

     

     

    WITH에서 GRADES를 만들어서 단계별 조건을 입력

    (GROUP BY의 절들은 모두 포함되어야 한다!!)

     

    SELECT에서 사번, 성명, 평가 등급, 성과금을 조회

    ORDER BY에서 사번을 오름차순 정렬

    WITH GRADES AS (
        SELECT E.EMP_NO, E.EMP_NAME, SAL, 
            CASE
                WHEN AVG(SCORE) >= 96 THEN 'S'
                WHEN AVG(SCORE) >= 90 THEN 'A'
                WHEN AVG(SCORE) >= 80 THEN 'B'
                ELSE 'C'
            END AS GRADE    
        FROM HR_EMPLOYEES E
        JOIN HR_GRADE G ON G.EMP_NO = E.EMP_NO
        GROUP BY E.EMP_NO, E.EMP_NAME, SAL
    )
    
    SELECT EMP_NO, EMP_NAME, GRADE, 
        CASE
            WHEN GRADE = 'S' THEN SAL*0.2
            WHEN GRADE = 'A' THEN SAL*0.15
            WHEN GRADE = 'B' THEN SAL*0.1
            WHEN GRADE = 'C' THEN SAL*0
        END BONUS
    FROM GRADES
    ORDER BY EMP_NO;

     

    String, Date

    카테고리 별 상품 개수 구하기(Lv2)

    문제 설명

     

    문제

    풀이

    SELECT에서 CATEGORY, PRODUCTS를 조회

    * SUBSTRING 기본 구문

    SUBSTRING(string, start, length) ​

    • string: 부분 문자열을 추출할 원본 문자열입니다.
    • start: 부분 문자열을 추출하기 시작할 위치(1부터 시작).
    • length: 추출할 문자의 수. 이 값이 없으면 시작 위치에서 끝까지 반환합니다.

     

    예제

    원본 문자열에서 "Hello World"의 일부를 추출하려고 할 때:

    SELECT SUBSTRING('Hello World', 1, 5);
    • 결과: Hello
    • 설명: 문자열 "Hello World"에서 첫 번째 문자부터 시작해서 5개의 문자를 추출합니다.

     

    GROUP BY에서 CATEGORY별로 그룹화

    ORDER BY에서 CATEGORY 기준으로 오름차순 정렬

    SELECT 
        SUBSTRING(PRODUCT_CODE, 1, 2) AS CATEGORY,
        COUNT(*) AS PRODUCTS
    FROM PRODUCT
    GROUP BY SUBSTRING(PRODUCT_CODE, 1, 2)
    ORDER BY CATEGORY ASC;