일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- MySQL
- 유데미코리아
- 데이터시각화
- 프리온보딩
- 유데미
- 데이터분석
- 코딩테스트
- 코테
- Tableau Desktop Specialist
- 쿼리테스트
- 프로그래머스
- 자격증준비
- 2024년
- 프로젝트
- 러닝스푼즈
- Python
- 파이썬
- 스타터스부트캠프
- 데이터분석가
- 자격증
- 태블로
- trouble shooting
- AICE
- 유데미부트캠프
- 실습
- 취업부트캠프
- 부트캠프후기
- SQL
- tableau
- 회고록
- Today
- Total
신이 되고 싶은 갓지이
SQL 코테 연습 프로그래머스 Lv.4 문제풀이 7 본문
1. 우유와 요거트가 담긴 장바구니 정답률 : 73%
프로그래머스
SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프
programmers.co.kr
문제
데이터 분석 팀에서는 우유(Milk)와 요거트(Yogurt)를 동시에 구입한 장바구니가 있는지 알아보려 합니다. 우유와 요거트를 동시에 구입한 장바구니의 아이디를 조회하는 SQL 문을 작성해주세요. 이때 결과는 장바구니의 아이디 순으로 나와야 합니다.
첫 트라이는 단순하게 '우유'와 '요거트'가 있는 cart_id만 뽑아서 그 수가 2 이상이면 가져오는것으로 진행했다. 그러나 실패하여 데이터를 확인해보니 우유를 2번 산 경우에 id가 다르기 때문에 요거트를 사지 않음에도 대상으로 잡히는 것을 확인했다. 이를 방지하기 위해 cart_id, name을 distinctg하게 뽑고, 그 이후에 count를 할까 했지만 두번의 서브쿼리가 뭔가 맘에 안 들어서 다른 방법을 생각해보았다.
-- 1. 실패
SELECT CART_ID
FROM (SELECT *, COUNT(NAME) OVER(PARTITION BY CART_ID) AS CNT
FROM CART_PRODUCTS
WHERE NAME IN ('Milk','Yogurt') ) A
WHERE CNT >=2
GROUP BY 1
ORDER BY 1
두번의 서브쿼리도 해보았는데 답은 맞았다. window함수가 where문에 쓸수가 없고, window에서는 count(distinct)가 불가했기 때문에 어쩔수 없이 두번의 서브쿼리를 사용한 결과이다.
-- 2. 두번의 서브쿼리
SELECT CART_ID
FROM (SELECT CART_ID, COUNT(NAME) OVER(PARTITION BY CART_ID) AS CNT
FROM (SELECT DISTINCT CART_ID, NAME
FROM CART_PRODUCTS
WHERE NAME IN ('Milk','Yogurt') ) A ) B
WHERE CNT >=2
GROUP BY 1
ORDER BY 1
마지막으로 생각한 방법은 임시 테이블을 사용하여 우유 테이블과 요거트 테이블을 만들어 inner join하는 방법이다.
-- 3.임시테이블로 실행
WITH MILK AS(
SELECT DISTINCT CART_ID
FROM CART_PRODUCTS
WHERE NAME='Milk'
), YOG AS(
SELECT DISTINCT CART_ID
FROM CART_PRODUCTS
WHERE NAME='Yogurt')
SELECT M.CART_ID
FROM MILK M
INNER JOIN YOG Y
ON M.CART_ID=Y.CART_ID
ORDER BY 1
다른 풀이들도 궁굼해서 찾아봤는데 아래와 같이 좀 더 간단한 방법들이 있었다. 코드는 항상 답이 맞았다고 끝낼것이 아니라 다른 사람들의 코드도 찾아보면서 더 효율적인 코드를 찾아보는게 좋은것 같다.
-- 4. INTERSECT 사용
SELECT CART_ID
FROM CART_PRODUCTS
WHERE NAME = "Milk"
INTERSECT
SELECT CART_ID
FROM CART_PRODUCTS
WHERE NAME = "Yogurt"
ORDER BY CART_ID
-- 5. having 절 사용
SELECT CART_ID
FROM CART_PRODUCTS
WHERE NAME IN ('Yogurt', 'Milk')
GROUP BY CART_ID
HAVING COUNT(DISTINCT NAME) >= 2
ORDER BY CART_ID ASC
2. 오프라인/온라인 판매 데이터 통합하기(SELECT) 정답률 : 66%
프로그래머스
SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프
programmers.co.kr
문제
ONLINE_SALE 테이블과 OFFLINE_SALE 테이블에서 2022년 3월의 오프라인/온라인 상품 판매 데이터의 판매 날짜, 상품ID, 유저ID, 판매량을 출력하는 SQL문을 작성해주세요. OFFLINE_SALE 테이블의 판매 데이터의 USER_ID 값은 NULL 로 표시해주세요. 결과는 판매일을 기준으로 오름차순 정렬해주시고 판매일이 같다면 상품 ID를 기준으로 오름차순, 상품ID까지 같다면 유저 ID를 기준으로 오름차순 정렬해주세요.
이 문제에서 처리해야할 부분은 일단 두 테이블을 붙여햐하는데, 방법이 join이 아닌 union이다. 해당 방법은 칼럼이 동일해야한다. 따라서 오프라인에는 없는 user_id를 채워주어야한다. 예시를 보면 해당 처리를 null로 했으니, NULL을 user_id로 칼럼을 채워주어서 두 테이블을 union all하면 완성이다.
-- 1.없는 칼럼은 만들어서 union all
(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")="202203")
UNION ALL
(SELECT DATE_FORMAT(SALES_DATE,"%Y-%m-%d") AS SALES_DATE, PRODUCT_ID, NULL AS USER_ID, SALES_AMOUNT
FROM OFFLINE_SALE
WHERE DATE_FORMAT(SALES_DATE,"%Y%m")="202203")
ORDER BY 1,2,3
'SQL' 카테고리의 다른 글
SQL 코테 연습 프로그래머스 Lv.5 문제풀이 9 (0) | 2025.03.01 |
---|---|
SQL 코테 연습 프로그래머스 Lv.4 문제풀이 8 (0) | 2025.02.26 |
SQL 코테 연습 프로그래머스 Lv.4 문제풀이 6 (0) | 2025.02.19 |
SQL 코테 연습 프로그래머스 Lv.4 문제풀이 5 (0) | 2025.02.18 |
SQL 코테 연습 프로그래머스 Lv.4 문제풀이 4 (2) | 2025.02.17 |