다음은 어느 의류 쇼핑몰의 온라인 상품 판매 정보를 담은 ONLINE_SALE 테이블과 오프라인 상품 판매 정보를 담은 OFFLINE_SALE 테이블 입니다.
ONLINE_SALE 테이블
ONLINE_SALE_ID | INTEGER | FALSE |
USER_ID | INTEGER | FALSE |
PRODUCT_ID | INTEGER | FALSE |
SALES_AMOUNT | INTEGER | FALSE |
SALES_DATE | DATE | FALSE |
OFFLINE_SALE 테이블
OFFLINE_SALE_ID | INTEGER | FALSE |
PRODUCT_ID | INTEGER | FALSE |
SALES_AMOUNT | INTEGER | FALSE |
SALES_DATE | DATE | FALSE |
문제
ONLINE_SALE 테이블과 OFFLINE_SALE 테이블에서 2022년 3월의 오프라인/온라인 상품 판매 데이터의 판매 날짜, 상품ID, 유저ID, 판매량을 출력하는 SQL문을 작성해주세요. OFFLINE_SALE 테이블의 판매 데이터의 USER_ID 값은 NULL 로 표시해주세요. 결과는 판매일을 기준으로 오름차순 정렬해주시고 판매일이 같다면 상품 ID를 기준으로 오름차순, 상품ID까지 같다면 유저 ID를 기준으로 오름차순 정렬해주세요.
풀이
항상 문제 속에서 요구하는 조건이 무엇인지 찾아내야 한다.
해당 문제에서는 1. user_id의 null값 포함 표시, 2. 3월의 판매 데이터, 3. 각 칼럼별 오름차순, 4. 온라인 테이블과 오프라인 테이블 조인이다.
조건을 찾았다면 각 조건이 어느 문법으로 쓰여야 하는지 파악하여야 한다.
SELECT DATE_FORMAT(SALES_DATE,'%Y-%m-%d') as SALES_DATE, PRODUCT_ID, NULL AS USER_ID, SALES_AMOUNT
FROM OFFLINE_SALE
WHERE SALES_DATE like '2022-03%'
union
SELECT DATE_FORMAT(SALES_DATE,'%Y-%m-%d')as SALES_DATE, PRODUCT_ID, USER_ID, SALES_AMOUNT
FROM ONLINE_SALE
WHERE SALES_DATE like '2022-03%'
order by sales_date,product_id,user_id;
1번 조건은 select 문에서 null as ~ 문법으로 작성해주었으며 2번 조건은 where 문에서 like '% 조건 %' 문법을 통해 22년 3월의 조건을 포함하는 데이터를 모두 불러와주었다. 3번 조건은 oder by를 사용하였으며 문제에서 요구하는 순서대로 작성해주었다. 4번 조건은 union을 사용하여 테이블의 값을 합쳐주었다.
다음은 식품의 정보를 담은 FOOD_PRODUCT 테이블입니다.
PRODUCT_ID | VARCHAR(10) | FALSE |
PRODUCT_NAME | VARCHAR(50) | FALSE |
PRODUCT_CD | VARCHAR(10) | TRUE |
CATEGORY | VARCHAR(10) | TRUE |
PRICE | NUMBER | TRUE |
문제
FOOD_PRODUCT 테이블에서 가격이 제일 비싼 식품의 식품 ID, 식품 이름, 식품 코드, 식품분류, 식품 가격을 조회하는 SQL문을 작성해주세요
풀이
처음 풀이로는
SELECT PRODUCT_ID, PRODUCT_NAME, PRODUCT_CD, CATEGORY, MAX(PRICE) as PRICE
FROM FOOD_PRODUCT;
와 같이 진행하였다.
하지만 MAX(PRICE)의 데이터와 나머지 칼럼의 데이터가 동일한 레코드의 데이터가 아니다.
따라서 다음과 같이 정렬을 활용한 풀이와
SELECT PRODUCT_ID, PRODUCT_NAME, PRODUCT_CD, CATEGORY, PRICE
FROM FOOD_PRODUCT
ORDER BY PRICE desc limit 1;
서브쿼리를 활용한 풀이가 가능하다.
SELECT PRODUCT_ID, PRODUCT_NAME, PRODUCT_CD, CATEGORY, PRICE
FROM FOOD_PRODUCT
WHERE PRICE = (SELECT MAX(PRICE) from food_product);
하지만 정렬을 활용하여 풀이하면 가격 내림차순 시 같은 가격이 존재할 때 limit 1로 인해 하나의 데이터만 나올 수 있는 위험성이 존재하기에 서브쿼리를 활용한 풀이가 더욱 안전하다고 할 수 있다.
다음은 식당의 정보를 담은 REST_INFO 테이블과 식당의 리뷰 정보를 담은 REST_REVIEW 테이블입니다.
REST_ID | VARCHAR(5) | FALSE |
REST_NAME | VARCHAR(50) | FALSE |
FOOD_TYPE | VARCHAR(20) | TRUE |
VIEWS | NUMBER | TRUE |
FAVORITES | NUMBER | TRUE |
PARKING_LOT | VARCHAR(1) | TRUE |
ADDRESS | VARCHAR(100) | TRUE |
TEL | VARCHAR(100) | TRUE |
REVIEW_ID | VARCHAR(10) | FALSE |
REST_ID | VARCHAR(10) | TRUE |
MEMBER_ID | VARCHAR(100) | TRUE |
REVIEW_SCORE | NUMBER | TRUE |
REVIEW_TEXT | VARCHAR(1000) | TRUE |
REVIEW_DATE | DATE | TRUE |
문제
REST_INFO와 REST_REVIEW 테이블에서 서울에 위치한 식당들의 식당 ID, 식당 이름, 음식 종류, 즐겨찾기수, 주소, 리뷰 평균 점수를 조회하는 SQL문을 작성해주세요. 이때 리뷰 평균점수는 소수점 세 번째 자리에서 반올림 해주시고 결과는 평균점수를 기준으로 내림차순 정렬해주시고, 평균점수가 같다면 즐겨찾기수를 기준으로 내림차순 정렬해주세요.
풀이
info테이블과 review테이블의 조인이 필요하다. 식당에 따른 리뷰 데이터를 가져와야 하기 때문에 동일한 컬럼인 ID컬럼을 통해 조인해야 한다. 뿐만 아니라 GROUP BY를 통해 ID별 스코어를 평균낼 수 있도록 해주어야 한다.
SELECT I.REST_ID, I.REST_NAME, I.FOOD_TYPE, I.FAVORITES, I.ADDRESS, ROUND(AVG(R.REVIEW_SCORE),2) as SCORE
FROM REST_INFO as I JOIN REST_REVIEW as R ON R.REST_ID = I.REST_ID
WHERE I.ADDRESS like '서울%'
GROUP BY I.REST_ID
ORDER BY SCORE desc, I.FAVORITES desc
'DB' 카테고리의 다른 글
데이터 시스템에 대하여 (0) | 2023.02.10 |
---|---|
프렌차이즈 레스토랑 DB구축 프로젝트 (0) | 2023.01.10 |