What a Beautiful Data!

solvesql 지역별 주문의 특징, 가구 판매의 비중이 높았던 날 찾기, 작품이 없는 작가 찾기 mysql

by darami

한문제 한문제 잘근 잘근 씹어먹기_SQL 성장기 🌟

지역별 주문의 특징

의문점 [해결]  왜 order_id를 DISTINCT 처리해줘야하는 걸까?

테이블마다 그 이유는 달랐지만 대부분 order_id를 DISTINCT 해줘야 했다.

이번 테이블에서는 한 order_id에 다양한 category, procuct_id가 있지만 몇개를 구매하든 '주문량'을 구해야하는 것임으로 distinct를 해주는 게 맞다고 이해했다. pivot table을 해주기에.   

SELECT Region
,COUNT(DISTINCT CASE WHEN category='Furniture' then order_id END) as Furniture
,COUNT(DISTINCT CASE WHEN category='Office Supplies' then order_id END) as 'Office Supplies'
,COUNT(DISTINCT CASE WHEN category='Technology' then order_id END) as Technology
FROM records
GROUP BY Region
ORDER BY Region

배운점

  • order_id 는 보통 카테고리, product_id 등이 달라도 distinct하게 해서 주문 수를 세주는게 맞다.
  • Pivot table 해줄 때 컬럼명을 띄어쓰기 포함해서 지정해 주려면 ' '를 붙여야한다. 아니면 에러가 난다. 

가구 판매의 비중이 높았던 날 찾기

 

풀이 1. 처음 내 풀이 

SELECT s.order_date as order_date
,s.f as furniture
,ROUND(s.f/(s.f+s.l)*100,2) as furniture_pct
FROM (
SELECT order_date
,COUNT(CASE WHEN category='Furniture' THEN order_id END) as f
,COUNT(CASE WHEN category<>'Furniture' THEN order_id END) as l
FROM records
GROUP BY order_date
HAVING (f+l)>=10
)s
WHERE ROUND(s.f/(s.f+s.l)*100,2)>=40
ORDER BY furniture_pct DESC

 

- 백분율이라서 100을 안 곱해줘서 그런 줄 알았는데, 곱해줘도 쿼리 결과가 달랐다. (쿼리 결과: 10개, 정답: 12개)

- 다른 분들의 풀이와 비교해보니 너무 이상하게 푼 것 같다.  이유: 알리야스를 지정해 쉽게 연산하고 싶었다. (흐유)

의문점 [미해결] - 사실 아직까지 왜 답이 안나오는지 명확하게 설명을 못하겠다. 쿼리 결과를 비교하면서 알아봐야지

풀이 1 쿼리 결과

풀이 2. 내 풀이 + 다른 분 풀이 

SELECT order_date
,COUNT(DISTINCT CASE WHEN category = 'Furniture' THEN order_id END)
AS furniture
,ROUND((COUNT(DISTINCT CASE WHEN category = 'Furniture' THEN order_id END)
/COUNT( DISTINCT order_id))*100,2) as furniture_pct
FROM records
GROUP BY order_date
HAVING COUNT(DISTINCT order_id) >= 10 AND furniture_pct >=40
ORDER BY furniture_pct DESC, order_date

 - 정답! , 정말 서브 쿼리 쓸 필요 없었는데.. 

뭐야.. 쿼리 결과가 아예 다르잖아...? ???

- 스터디 시간에 같이 해결해보도록 하자.

 

풀이 3. 스터디원분 풀이 

SELECT order_date
, COUNT(DISTINCT IF(category = 'Furniture', order_id, NULL)) furniture
, ROUND(COUNT(DISTINCT IF(category = 'Furniture', order_id, NULL))*100
/ COUNT(DISTINCT order_id), 2) furniture_pct
FROM records
GROUP BY order_date
HAVING COUNT(DISTINCT order_id) >= 10
AND furniture_pct >= 40.0
ORDER BY furniture_pct DESC, order_date

- IF 문을 쓰셨다. 나는 IF문을 거의 쓰지 않아서 몰랐는데, 이번 기회에 다시 배워보도록하자. 

아하
- CASE 문과 논리는 같은데 더 간단하게 쓸 수 있는 것 같다.

 

풀이 4. 스터디원분 풀이 

- 위의 풀이 3과 같은데 Where절에서 데이터 용량을 끊어주면 성능이 높아진다는 것에 착안하셔서 코드를 짜셨다고 한다.

  데이터 수가 많을 때하면 정말 좋을듯! 

 

배운점 

  •  ID를 SUM을 해주면 안되지 COUNT해줘야지!
  • IF(조건,참일때 반환,거짓일 때 반환)
  • 계산식 집계함수 써서 길어진다고 서브쿼리로 더 복잡하게 하는 건 정말 아니야... 
  • 다양한 문제 풀이 방법과 성능 향상을 고민해봐야지 비로소 나의 헛점을 깨닫고 더 성장할 수 있다. 

작품이 없는 작가 찾기

SELECT aa.artist_id as artist_id
,aa.name as name
FROM artists aa
WHERE aa.artist_id NOT IN
(SELECT DISTINCT a.artist_id
FROM artworks_artists as w
JOIN artists a ON a.artist_id=w.artist_id)
AND aa.death_year IS NOT NULL

- 쉽네! 라고 생각했다. 그런데 또... 정말 쓸데 없이 서브 쿼리를 쓰는 거 왜그런거죠..? 

 

(스터디원분 풀이)

하하 ㅎㅎㅎ 

 

배운점

  • 서브 쿼리 못잃어 병 걸린 것 같다.
  • 혼자 풀고 넘어갔으면 무조건 히히 하고 문제 없어! 했을듯.. 역시 이렇게 다양한 문제풀이를 비교해봐야 해! 
블로그의 프로필 사진

블로그의 정보

다람

darami

활동하기