개인공부

[SQL] LEFT JOIN 과 INNER JOIN 차이 2

여연찌 2024. 3. 22. 12:45

지난번 답하지 못했던 질문을 이어서 작성

 

https://lyj-01.tistory.com/6

 

LEFT JOIN 과 INNER JOIN 차이

식당별 평균 음식 주문 금액과 주문자의 평균 연령을 기반으로 Segmentation 하기 - 평균 음식 주문 금액 기준 : 5,000 / 10,000 / 30,000 / 30,000 초과 - 평균 연령 : ~ 20대 / 30대 / 40대 / 50대 이상 -- 내가 작성

lyj-01.tistory.com

 

  • < 해결되지 않았던 질문 >

 

Q. 이 데이터 중에 왜 'wichcraft' 행만 출력이 되었는지?

Q. GROUP BY 를 하지 않았을 경우 1개의 행만 추출을 하는데 왜일까?

 

 

 


 

 

 

 

Q. LEFT JOIN 한 값과, INNER JOIN 한 값은 어떤 차이가 있을까?

SELECT restaurant_name
     , CASE WHEN AVG(A_price) <= 5000 THEN 'price_group1'
            WHEN AVG(A_price) > 5000 AND AVG(A_price) <= 10000 THEN 'price_group2'
            WHEN AVG(A_price) > 10000 AND AVG(A_price) <= 30000 THEN 'price_group3'
            WHEN AVG(A_price) > 30000  THEN 'price_group4'
            END "평균음식주문금액"
     , CASE WHEN AVG(A_age) < 30 THEN 'age_group1'
            WHEN AVG(A_age) BETWEEN 30 AND 39 THEN 'age_group2'
            WHEN AVG(A_age) BETWEEN 40 AND 49 THEN 'age_group3'
            ELSE 'age_group4'
            END "평균연령"
     , age
     , price
FROM
(
SELECT f.restaurant_name
     , AVG(f.price) A_price
     , AVG(c.age) A_age
     , c.age
     , f.price
FROM food_orders f LEFT JOIN customers c ON f.customer_id = c.customer_id 
GROUP BY 1
) a
GROUP BY 1
ORDER BY age

select restaurant_name,
       case when price <=5000 then 'price_group1'
            when price >5000 and price <=10000 then 'price_group2'
            when price >10000 and price <=30000 then 'price_group3'
            when price >30000 then 'price_group4' end price_group,
       case when age <30 then 'age_group1'
            when age between 31 and 39 then 'age_group2'
            when age between 40 and 49 then 'age_group3'
            else 'age_group4' end age_group,
       a,
       p
from
(
select a.restaurant_name,
       avg(price) price,
       avg(age) age,
       age a,
       price p
from food_orders a inner join customers b on a.customer_id=b.customer_id
group by 1
) t
order by a

A.

ㅡㅡ wichcraft 는 왜 자꾸 나오는지..?

생각해보니 고객 컬럼에 NULL 값이어도 불러오는 LEFT JOIN 을 사용했기 때문이다..

이 문제의 경우 '식당별 평균 음식 주문 금액과 주문자의 평균 연령을 기반으로 Segmentation 하기' 이기 때문에

INNER JOIN 을 하는 것이 알맞다!

 

 

 

+ 다시한번 문제풀이

(참고)

- 평균 음식 주문 금액 기준 : 5,000 / 10,000 / 30,000 / 30,000 초과

- 평균 연령 : ~ 20대 / 30대 / 40대 / 50대 이상

 

SELECT restaurant_name
     , CASE WHEN price <= 5000 THEN 'price_group1'
            WHEN price > 5000 AND price <= 10000 THEN 'price_group2'
            WHEN price > 10000 AND price <= 30000 THEN 'price_group3'
            WHEN price > 30000 THEN 'price_group4'
            END price_group
     , CASE WHEN age < 30 THEN 'age_group1'
            WHEN age >= 31 AND 39 THEN 'age_group2'
            WHEN age >= 41 AND 49 THEN 'age_group3'
            WHEN age >= 50 THEN 'age_group4'
            END age_group
FROM 
(
SELECT restaurant_name
     , AVG(price) price
     , AVG(age) age
FROM food_orders f INNER JOIN customers c ON f.customer_id = c.customer_id 
GROUP BY restaurant_name
) a
ORDER BY 1

 

+

해결이 되지 않았던 이유가 너무 간단한 원인이었다 

이렇게 길게 풀어봤으니까 다음에는 INNER 와 LEFT 를 헷갈리지 않을 듯

 

 

 

 

Q. GROUP BY 를 하지 않았을 경우 1개의 행만 추출을 하는데 왜일까?

SELECT restaurant_name
     , CASE WHEN AVG(A_price) <= 5000 THEN 'price_group1'
            WHEN AVG(A_price) > 5000 AND AVG(A_price) <= 10000 THEN 'price_group2'
            WHEN AVG(A_price) > 10000 AND AVG(A_price) <= 30000 THEN 'price_group3'
            WHEN AVG(A_price) > 30000  THEN 'price_group4'
            END "평균음식주문금액"
     , CASE WHEN AVG(A_age) < 30 THEN 'age_group1'
            WHEN AVG(A_age) BETWEEN 30 AND 39 THEN 'age_group2'
            WHEN AVG(A_age) BETWEEN 40 AND 49 THEN 'age_group3'
            ELSE 'age_group4'
            END "평균연령"
     , age
     , price
FROM
(
SELECT f.restaurant_name
     , AVG(f.price) A_price
     , AVG(c.age) A_age
     , c.age
     , f.price
FROM food_orders f LEFT JOIN customers c ON f.customer_id = c.customer_id 
GROUP BY 1
) a
-- GROUP BY 1
ORDER BY age

+

주문이력 테이블의 제일 첫번째 행인 'Hangawi' 값이 추출된다

 

 

Q-1 LEFT JOIN 을 사용한 후 GROUP BY 를 했을 경우 'wichcraft' 라는 행이 추가로 추출되는데

age 가 NULL 이 아닌 조건을 사용하지 않았기 때문에

CASE 문을 순서대로 하고 마지막 그 외 값인 age_group4 가 입력이 되었다.

 

이후 메인쿼리에서 Segmentation 해야하는데 'wichcraft'  행의 age 가  NULL 값이 때문에

어떤 데이터에 어떤 정보가 입력되어야 하는지 알 수 없어

제일 첫번째 행이 추출된 것으로 예상된다..

 

 

위는 내 예상,, ? 

쓰면서도 잘 모르겠음

 

튜터님께 여쭤보고 해결되면 수정할 것!

 

 


 

 

Q. 이 데이터 중에 왜 'wichcraft' 행만 출력이 되었는지?

A.

wichcraft 음식점만이 유일하게 고객데이터가 100% 없다!

다른 음식점의 경우 고객데이터가 없는 것도 있고, 있는 것도 있다.

 

 

Q. GROUP BY 를 하지 않았을 경우 1개의 행만 추출을 하는데 왜일까?

A.

SQL 작동 방식에 의해서 GROUP BY 하지 않는 다른 조회컬럼에서는

첫번째 데이터만 불러온다!