>

TIL

SQL JOIN, UNION, 그리고 DATE_FORMAT

ekdud 2024. 12. 5. 11:24

📑

     

    INNER JOIN

    일반조인 = 내부조인 = 동등조인
    일반조인은 조인 조건문에 따라 2개의 테이블의 컬럼을 합쳐 새로운 테이블을 생성한다.

     

    1. 암묵적 표현법

     결합 조건이 되는 칼럼을 WHERE절에 지정한다.

    2. 명시적 표현법

     FROM절에 테이블 나열 시 JOIN을 넣어주고, ON으로 결합 조건이 되는 칼럼을 지정해준다.

    SELECT 열 목록
    FROM 첫 번째 테이블
        INNER JOIN 두 번째 테이블
        ON 조인 조건
    [WHERE 검색 조건]
    
    # INNER JOIN의 INNER는 생략해도 INNER JOIN으로 인식함.

     

     

    OUTER JOIN

    SELECT 열 목록
    FROM 첫 번째 테이블(LEFT 테이블)
        LEFT | RIGHT | FULL OUTER JOIN 두 번째 테이블(RIGHT 테이블)
         ON 조인 조건
    [WHERE 검색 조건] # 상황에 따라 사용

     

     

    🔗 <== JOIN 정리해놓은 것. 참고.

     

     


     

     

    UNION

    - UNION

    : 여러 쿼리문들을 합쳐서 하나의 쿼리문으로 만들어주는 방법. 중복된 값을 제거하는 연산이 추가로 수행되기 때문에 UNION ALL보다 속도가 느리다.

     

    - UNION ALL

    : UNION과 동일하게 여러 쿼리문들을 합쳐서 하나의 쿼리문으로 만들어주는 방법. 중복된 값을 모두 보여준다.

     

     


     

     

    DATE_FORMAT

    SELECT DATE_FORMAT(NOW(),'%Y-%m-%d') AS 이름지정
    구분기호 역할 구분기호 역할
    %Y 4자리 년도 %m 숫자 월(반드시 두자리)
    %y 2자리 년도 %c 숫자 월(한자리는 한자리)
    %M 긴 월(ex. January) %d 일자(반드시 두자리)
    %b 짧은 월(ex. Jan) %e 일자(한자리는 한자리)
    %W 긴 요일 이름(ex. Monday) %I 시간(12시간)
    %a 짧은 요일 이름(ex. Mon) %H 시간(24시간)
    %i %r hh:mm:ss AM, PM
    %T hh:mm:ss %S

     

     

     

    *YEAR, MONTH, DAY 함수

    # 2024-01-01 ~ 2024-06-30 사이의 월별 평균 매출액과 합계.
    SELECT 	DATE_FORMAT(RCV_ORD_DE, '%m') AS '월',
    		AVG(SELL_AM) '평균매출액'
    FROM T_DALY_ORDDE_SM_RSLT
    WHERE RCV_ORD_DE BETWEEN '2024-01-01' AND '2024-06-30'
    GROUP BY 월
    ORDER BY 월;
    
    # 위의 쿼리와 거의 같음
    SELECT 	MONTH(RCV_ORD_DE) AS '월',
    		AVG(SELL_AM) '평균매출액'
    FROM T_DALY_ORDDE_SM_RSLT
    WHERE RCV_ORD_DE BETWEEN '2024-01-01' AND '2024-06-30'
    GROUP BY 월
    ORDER BY 월;

    MONTH함수를 사용하는 경우에는 월이 01, 02과 같이 반환되지 않고 1, 2로 반환된다.

     


     

    SQL CODE KATA

    Ⅰ. 문제 전문은 아래 링크 참고. 다음은 아이스크림 가게의 상반기 주문 정보를 담은 FIRST_HALF 테이블과 아이스크림 성분에 대한 정보를 담은 ICECREAM_INFO 테이블입니다. FIRST_HALF 테이블 구조는 다음과 같으며, SHIPMENT_ID, FLAVOR, TOTAL_ORDER 는 각각 아이스크림 공장에서 아이스크림 가게까지의 출하 번호, 아이스크림 맛, 상반기 아이스크림 총주문량을 나타냅니다. FIRST_HALF 테이블의 기본 키는 FLAVOR입니다.

    ICECREAM_INFO 테이블 구조는 다음과 같으며, FLAVOR, INGREDITENT_TYPE은 각각 아이스크림 맛, 아이스크림의 성분 타입을 나타냅니다. INGREDIENT_TYPE에는 아이스크림의 주 성분이 설탕이면 sugar_based라고 입력되고, 아이스크림의 주 성분이 과일이면 fruit_based라고 입력됩니다. ICECREAM_INFO의 기본 키는 FLAVOR입니다. ICECREAM_INFO테이블의 FLAVOR는 FIRST_HALF 테이블의 FLAVOR의 외래 키입니다.

     

    상반기 아이스크림 총주문량이 3,000보다 높으면서 아이스크림의 주 성분이 과일인 아이스크림의 맛을 총주문량이 큰 순서대로 조회하는 SQL 문을 작성해주세요.

    (school.programmers.co.kr)

    SELECT FIRST_HALF.FLAVOR
    FROM FIRST_HALF JOIN ICECREAM_INFO
    ON FIRST_HALF.FLAVOR = ICECREAM_INFO.FLAVOR
    WHERE FIRST_HALF.TOTAL_ORDER>3000 AND ICECREAM_INFO.INGREDIENT_TYPE='fruit_based'
    ORDER BY FIRST_HALF.TOTAL_ORDER DESC;

     

     

    Ⅱ. 문제 전문은 아래 링크 참고. REST_INFO와 REST_REVIEW 테이블에서 서울에 위치한 식당들의 식당 ID, 식당 이름, 음식 종류, 즐겨찾기수, 주소, 리뷰 평균 점수를 조회하는 SQL문을 작성해주세요. 이때 리뷰 평균점수는 소수점 세 번째 자리에서 반올림 해주시고 결과는 평균점수를 기준으로 내림차순 정렬해주시고, 평균점수가 같다면 즐겨찾기수를 기준으로 내림차순 정렬해주세요. (school.programmers.co.kr)

    SELECT REST_INFO.REST_ID, REST_NAME, FOOD_TYPE, FAVORITES, ADDRESS, ROUND(AVG(REVIEW_SCORE), 2) AS SCORE
    FROM REST_INFO JOIN REST_REVIEW
    ON REST_INFO.REST_ID = REST_REVIEW.REST_ID
    WHERE ADDRESS LIKE '서울%'
    GROUP BY REST_INFO.REST_ID, REST_NAME, FOOD_TYPE, FAVORITES, ADDRESS, FAVORITES
    ORDER BY SCORE DESC, FAVORITES DESC;

     

     

    Ⅲ. 문제 전문은 아래 링크 참고. ONLINE_SALE 테이블과 OFFLINE_SALE 테이블에서 2022년 3월의 오프라인/온라인 상품 판매 데이터의 판매 날짜, 상품ID, 유저ID, 판매량을 출력하는 SQL문을 작성해주세요. OFFLINE_SALE 테이블의 판매 데이터의 USER_ID 값은 NULL 로 표시해주세요. 결과는 판매일을 기준으로 오름차순 정렬해주시고 판매일이 같다면 상품 ID를 기준으로 오름차순, 상품ID까지 같다면 유저 ID를 기준으로 오름차순 정렬해주세요. (school.programmers.co.kr)

    SELECT DATE_FORMAT(SALES_DATE, '%Y-%m-%d') as SALES_DATE,
        PRODUCT_ID, 
        USER_ID, 
        SALES_AMOUNT
    FROM ONLINE_SALE 
    WHERE DATE_FORMAT(SALES_DATE, '%Y-%m') = '2022-03'
    
    UNION
    
    SELECT DATE_FORMAT(SALES_DATE, '%Y-%m-%d') as SALES_DATE,
        PRODUCT_ID, 
        NULL as USER_ID, 
        # OFFLINE_SALE테이블은 USER_ID 칼럽이 없기 때문에 USER_ID 컬럼의 값을 NULL로 넣어서 표시.
        SALES_AMOUNT
    FROM OFFLINE_SALE  
    WHERE DATE_FORMAT(SALES_DATE, '%Y-%m') = '2022-03'
    ORDER BY SALES_DATE, PRODUCT_ID, USER_ID;

     

     

    Ⅳ. 문제 전문은 아래 링크 참고. 아이템의 희귀도가 'RARE'인 아이템들의 모든 다음 업그레이드 아이템의 아이템 ID(ITEM_ID), 아이템 명(ITEM_NAME), 아이템의 희귀도(RARITY)를 출력하는 SQL 문을 작성해 주세요. 이때 결과는 아이템 ID를 기준으로 내림차순 정렬해주세요. (school.programmers.co.kr)

    SELECT ITEM_INFO.ITEM_ID, ITEM_NAME, RARITY
    FROM ITEM_INFO JOIN ITEM_TREE 
    ON ITEM_INFO.ITEM_ID = ITEM_TREE.ITEM_ID
    WHERE PARENT_ITEM_ID IN (
        SELECT ITEM_ID 
        FROM ITEM_INFO 
        WHERE RARITY = 'RARE'
    )
    ORDER BY ITEM_INFO.ITEM_ID DESC;