📕 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로 데이터가 조회되지 않는다.
- NOT IN 연산은 AND연산으로, 서브쿼리의 모든 반환값과 ≠연산한 결과가 TRUE인 경만 데이터가 조회가 된다.
- 왜 NULL값을 제거해야할까?
- 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;