📕 SQL/MySQL

📕[SQL] 24.08.01 SQL

혜덕hyeduck 2024. 8. 1. 19:25

SQL ) LV2. 조건에 맞는 개발자 찾기

접근법

  • 두 테이블간 합병가능한 조건이 없으므로 카티션 프로덕트 수행 : FROM 테이블A a, 테이블B b
  • 조건 절에서 NAME값이 Python이나 C#인 경우와 두테이블의 코드를 & 비트 연산한 값이 TRUE(1)인 경우에만 조회
    • 비트연산
      • & : 대응되는 비트가 모두 1이면 1 반환
      • | : 대응되는 비트 중 하나라도 1이면 1반환
      • * : 대응되는 비트가 서로 다르면 1 반환
      • ~ : 비트 1 → 0, 0 → 1
      • << : 지정된 크기만큼 비트를 왼쪽 이동
      • >> : 지정된 크기만큼 비트를 오른쪽 이동
  • 이때 데이터 조회 시 DISTINCT 키워드로 중복된 튜플 제거할 것

코드

-- 문제 : DEVELOPERS 테이블에서 Python이나 C#스킬을 가진 개발자 정보 조회 / 결과는 ID기준 오름차순
-- 조회할 정보 : ID, EMAIL, FIRST_NAME, LAST_NAME
SELECT DISTINCT D.ID, D.EMAIL, D.FIRST_NAME, D.LAST_NAME
FROM DEVELOPERS D, SKILLCODES S
WHERE 
    S.NAME IN ('Python', 'C#') AND
    D.SKILL_CODE & S.CODE
ORDER BY D.ID ASC;

 

SQL ) LV4. 자동차 대여 기록에서 대여중 / 대여 가능 여부 구분하기

접근법

  • CASE문을 사용
    • 서브쿼리로 대여기간에 2022-10-16이 포함되어 있는 경우의 CAR_ID값을 반환
    • 이때 반환값에 속할 경우 ‘대여중’
    • 그게 아닐 경우 ‘대여 가능’을 값으로 갖는 AVAILABILITY 칼럼 생성
  • 여기서 주의할 점은
    • NOT BETWEEN을 기준으로 찾게 되면, 한 번이라도 대여기간에 포함되지 않을 경우에도 CAR_ID를 반환시켜버린다.
    • 여기서는 BETWEEN연산을 통해 한번이라도 대여기간에 2022-10-16 날짜가 포함된 경우에 CAR_ID를 반환시켜 ‘대여중’으로 표기해야 함
  • 최종적으로 CAR_ID가 여러개 나오므로 CAR_ID기준 GROUP BY나 DISTINCT 키워드를 사용해 출력

코드

-- [문제]
-- 2022년 10월 16일에 자동차가 대여 중이라면 대여중, 그게 아니라면 대여가능 출력
-- 자동차 ID기준 내림차순 정렬
SELECT CAR_ID, 
    CASE 
        WHEN CAR_ID IN (SELECT DISTINCT CAR_ID 
                        FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY
                        WHERE '2022-10-16' BETWEEN START_DATE AND END_DATE) THEN '대여중'
        ELSE '대여 가능'
    END 'AVAILABILITY'
FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY
GROUP BY CAR_ID
ORDER BY CAR_ID DESC;

 

SQL ) LV3. 업그레이드 할 수 없는 아이템 구하기

접근법

  • 서브쿼리로 PARENT_ITEM_ID의 값들을 중복과 NULL값을 제거해서 반환
    • 왜 NULL값을 제거해야할까?
      • NOT IN 연산은 AND연산으로, 서브쿼리의 모든 반환값과 ≠연산한 결과가 TRUE인 경만 데이터가 조회가 된다.
        • 이때, NULL과 ≠ 연산을 하게 되면 FALSE가 반환되므로 결국 최종 연산 결과가 FALSE로 데이터가 조회되지 않는다.
  • WHERE절에서 서브쿼리의 반환값을 갖지 않는 ITEM_ID만 조회

코드

-- [문제]
-- 이 문제에서 더 이상 업그레이드 할 수 없는 아이템 == 리프노드
-- 즉, 자신을 부모노드로 갖는 ITEM이 없는 경우에만 데이터 조회

SELECT ITEM_ID, ITEM_NAME, RARITY
FROM ITEM_INFO
WHERE ITEM_ID NOT IN (SELECT DISTINCT PARENT_ITEM_ID FROM ITEM_TREE WHERE PARENT_ITEM_ID IS NOT NULL)
ORDER BY ITEM_ID DESC;

 

SQL ) LV3. 있었는데요 없었습니다

코드

-- [문제]
-- 보호 시작일보다 입양일이 더 빠른 동물의 아이디와 이름 조회
-- ANIMAL_INS : 보호소에 들어온 동물 정보
-- ANIMAL_OUTS : 보호소에서 입양보낸 동물 정보
SELECT I.ANIMAL_ID, I.NAME
FROM ANIMAL_INS I JOIN ANIMAL_OUTS O ON I.ANIMAL_ID = O.ANIMAL_ID
WHERE I.DATETIME > O.DATETIME
ORDER BY I.DATETIME ASC;

 

SQL ) LV2. 조건에 맞는 아이템들의 가격의 총합 구하기

코드

SELECT SUM(PRICE) AS 'TOTAL_PRICE'
FROM ITEM_INFO
GROUP BY RARITY
HAVING RARITY = 'LEGEND';

 

SQL ) LV3. 조건별로 분류하여 주문상태 출력하기

코드

-- [문제]
-- 출고여부 칼럼을 생성하여
-- 2022년 5월 1일까지는 출고 완료로
-- 그 이후는 출고 대기로
-- 미정일 경우 출고미정으로 출력
-- 결과는 주문ID 기준 오름차순 정렬

SELECT ORDER_ID, PRODUCT_ID, DATE_FORMAT(OUT_DATE, '%Y-%m-%d'), 
    CASE 
        WHEN OUT_DATE <= '2022-05-01' THEN '출고완료'
        WHEN OUT_DATE > '2022-05-01' THEN '출고대기'
        ELSE '출고미정'
    END AS '출고여부'
FROM FOOD_ORDER
ORDER BY ORDER_ID ASC;