AI SCHOOL/SQL

[SQL] JOIN 연습문제

moru_xz 2023. 1. 26. 16:51

SQL 연습문제 8-1

회원(users) 테이블과 주문정보(orders) 테이블을 이용하여 모든 주문내역에 회원정보를 표시하세요.

  • 조회 항목 : 주문ID(order_id), 주문한 상품 수량(num_of_item), 회원 이름(first_name, last_name), 주소(street_address), 우편번호(postal_code), 도시(city), 국가(country)
SELECT 
  t2.order_id,
  t2.num_of_item,
  t1.first_name,
  t1.last_name,
  t1.street_address,
  t1.postal_code,
  t1.city,
  t1.country
  
FROM `thelook_ecommerce.users` as t1
left join `thelook_ecommerce.orders` as t2 on t1.id = t2.user_id

t1.first_name 하는 이유? 뭐징? 근데 그냥 first_name 해도 답 나옴.. -> 명시용 

SQL 연습문제 8-2

회원(users) 테이블과 주문정보(orders) 테이블을 이용하여 상품을 주문한 회원의 국가가 ‘United States’이면서 주문 상태가 처리중(Processing)인 정보를 조회하시오.

  • 조회 항목 : 회원 이름(first_name, last_name), 주소(street_address), 우편번호(postal_code), 도시(city), 국가(country), 주문한 상품 수량(num_of_item)
  • 조건 : 국가가 ‘United States’이면서 주문 상태가 처리중(Processing)

<내가>

SELECT 
  t2.order_id,
  t1.first_name,
  t1.last_name,
  t1.street_address,
  t1.postal_code,
  t1.city,
  t1.country,
  t2.num_of_item
FROM `thelook_ecommerce.users` as t1
left join `thelook_ecommerce.orders` as t2 on t1.id = t2.user_id

where t1.country = 'United States' and t2.status = 'Processing'

<강사님>

select 
  t1.order_id,
  t2.first_name || ' ' ||t2.last_name as user_name,
  t2.street_address,
  t2.postal_code,
  t2.city,
  t2.country,
  t1.num_of_item
from `thelook_ecommerce.orders` t1
join `thelook_ecommerce.users` t2 on t1.user_id = t2.id
where t2.country = 'United States'
and t1.status = 'Processing'

왜 join이지? left join 안 쓰고?  -> 잘 관리되면 join 써도되는 건가?

 

 마스터테이블인 user나 product에 해당 id의 레코드가 없는경우
inner join의 경우에는 order 테이블 레코드도 출력이 안될 수 있어요.
예) 1번 주문에 user_id가 10인데 user 테이블에 10번 유저 데이터가 아예 없는 경우

order테이블에서 2022년 전체 매출기록을 조회하는데 
탈퇴한 10번유저의 주문기록만 빠져서는 안되겠죠.

그러다보니 저의 경우에는 의도적으로 left join만 사용하는 습관이 생겨버렸네요.

관리가 잘 되어있다는 것은
order테이블에 기록되어있는 user_id에 해당하는 모든 id의 유저가
user테이블에도 다 레코드가 존재가는것을 이야기 한 것 이예요.

 

=> 잘 관리된 테이블은 null 값이 없는 것 -> 그래서 매치가 잘 되는 

 

 

회원이 탈퇴 할 경우 -> 삭제하지 않고 탈퇴 한 회원이라고 표시를 함(회원 id, 가입, 탈퇴 일시 정도) -> 소프트 딜리트 

 

SQL 연습문제 8-3

회원(users) 테이블과 주문정보(orders) 테이블을 이용하여 국가별 총 상품 주문주(total_order_count)을 조회하시오.

  • 조회 항목 : 국가명(country), 국가별 총 상품 주문주(total_order_count)
  • 정렬 : 국가별 총 상품 주문주(total_order_count)이 많은 순으로 정렬
select t1.country,
      count(t2.order_id) as total_order_count

from `thelook_ecommerce.users` as t1
left join `thelook_ecommerce.orders` as t2 on t1.id = t2.user_id

group by country
order by total_order_count desc

 

 

SQL 연습문제 8-4

주문상품(order_items) 테이블과 상품정보(products) 테이블을 이용하여 필요한 정보를 조회하시오.

  • 조회 항목 : 가격(cost), 카테고리(category), 상품명(name), 브랜드(brand), 판매가격(retail_price), 주문상태(status), 주문일시(created_at), 배송일시(shipped_at), 배송완료일시(delivered_at)
  • 조건 : 카테고리(category)가 'Outerwear & Coats'
  • 정렬 : 주문일시(created_at) 기준으로 최신순으로 정렬
select 
      t1.id as order_item_id,
      t1.order_id,
      t2.cost,
      t2.category,
      t2.name,
      t2.brand,
      t2.retail_price,
      t1.status,
      t1.created_at,
      t1.shipped_at,
      t1.delivered_at

from `thelook_ecommerce.order_items` as t1
left join `thelook_ecommerce.products` as t2 on t1.id = t2.id
where t2.category = 'Outerwear & Coats'
order by t1.created_at desc

 

 

SQL 연습문제 8-5

주문상품(order_items) 테이블과 상품정보(products) 테이블을 이용하여 2022년 한해 주문한 상품들의 정보를 조회하시오.

  • 조회 항목 : 주문일(order_date), 상품명(name), 주문상태(status), 원가(cost), 판매가격(retail_price), 카테고리(category), 브랜드(brand)
  • 주문일은 2022-01-01 와 같은 %Y-%m-%d 포맷으로 표시해주세요. FORMAT_DATE 함수 이용합니다. order_items의 created_at을 데이터를 사용하여 조회하면 됩니다.
  • 조회 조건
    • 주문일시 : 2022-01-01 ~ 2022-12-31
  • 정렬 조건 : 주문일시(created_at) 오름차순
select 
      format_date('%Y-%m-%d', t1.created_at) as order_date,
      t2.name,
      t1.status,
      t2.cost,
      t2.retail_price,
      t2.category,
      t2.brand,

from `thelook_ecommerce.order_items` as t1
left join `thelook_ecommerce.products` as t2 on t1.product_id = t2.id
where t1.created_at between '2022-01-01' and  '2022-12-31'
order by created_at

날짜 between 써라 

<=, > 잘 못 쓸 것 같으면 그냥 between 써라 

 

SQL 연습문제 8-6

주문상품(order_items) 테이블과 상품정보(products) 테이블을 이용하여 주문한 상품의 브랜드 별 평균할인가격(brand_avg_sale_price)을 조회하시오.

  • 조회 항목 : 브랜드(brand), 브랜드 별 평균할인가격(brand_avg_sale_price)
  • 정렬 : 브랜드명으로 정렬
select 
      t2.brand,
      avg(t1.sale_price) as brand_avg_sale_price
from `thelook_ecommerce.order_items` as t1
left join `thelook_ecommerce.products` as t2 on t1.product_id = t2.id
group by t2.brand
order by t2.brand

t1.product_id = t2.id 가 답 근데 처음에 t1.id = t2.id로 했었음 잘 확인하고!! -> 근데 내가 그걸 어떻게 알지? 

SQL 연습문제 8-7

주문상품(order_items) 테이블과 상품정보(products) 테이블을 이용하여

여성파트 주문완료상품의 날짜별 상품별 매출합계과 평균매출을 구하세요.

단 주문건수가 2개이상인 데이터만 표시하세요.

조회항목

  • 주문일 (order_date)
    • 표시 형식 : 2022-01-01
  • 상품명 (product_name)
  • 주문건수 (order_item_count)
  • 매출합계 (sum_sale_price) - 소수점 2자리까지 표시, 반올림
  • 평균매출(avg_sale_price) - 소수점 2자리까지 표시, 반올림

필터 조건

  • 상품의 department가 Women 입니다.
  • 주문의 상태가 Complete 인 주문만 포함합니다.
  • 주문건수가 2개 이상 데이터만 표시

정렬조건

  • 주문일 오름차순
  • 상품명 오름차순

 

SQL 연습문제 8-8

주문상품(order_items) 테이블과 상품정보(products) 테이블을 이용하여 주문id 당 매출 합계 정보를 구하세요.

group by order_id를 이용하세요.

  • 조회 항목 :
    • 주문 id(order_id)
    • 비용 합계(sum_cost)
    • 판매가격 합계(sum_retail_price)
    • 총 이익(sum_profit)
select
  t1.order_id,
  sum(t2.cost) as sum_cost,
  sum(t2.retail_price) as sum_retail_price,
  sum(t2.retail_price - t2.cost) as sum_profit

from `thelook_ecommerce.order_items` as t1
left join `thelook_ecommerce.products` as t2 on t1.product_id = t2.id
group by order_id
order by order_id

 

SQL 연습문제 8-9

사용자 이벤트(events) 테이블에서 일별 이벤트타입별 이벤트 발생 횟수를 조회해보세요.

조회항목

  • 이벤트 발생일(date)
  • home 이벤트 횟수 (home)
  • department 이벤트 횟수 (department)
  • product 이벤트 횟수 (product)
  • cart 이벤트 횟수 (cart)
  • purchase 이벤트 횟수 (purchase)
  • cancel 이벤트 횟수 (cancel)

정렬순서

  • 이벤트 발생인 오름차순
select
  format_date('%Y-%m-%d', created_at) as date, 
  count(case when event_type = 'home' then 1 end) as home,
  count(case when event_type = 'department' then 1 end) as department,
  count(case when event_type = 'product' then 1 end) as product,
  count(case when event_type = 'cart' then 1 end) as cart,
  count(case when event_type = 'purchase' then 1 end) as purchase,
  count(case when event_type = 'cancel' then 1 end) as cancel

from `thelook_ecommerce.events`
group by date
order by date

 


프로그래머스 문제 8-1 (level 1)

상반기 아이스크림 총주문량이 3,000보다 높으면서 아이스크림의 주 성분이 과일인 아이스크림의 맛을 총주문량이 큰 순서대로 조회하는 SQL 문을 작성해주세요.

SELECT T2.FLAVOR
FROM ICECREAM_INFO AS T1
LEFT JOIN FIRST_HALF AS T2 ON T1.FLAVOR = T2.FLAVOR 
WHERE TOTAL_ORDER > 3000 AND INGREDIENT_TYPE = 'fruit_based'
GROUP BY FLAVOR
ORDER BY TOTAL_ORDER DESC

프로그래머스 문제 8-2 (level 2)

PRODUCT 테이블과 OFFLINE_SALE 테이블에서 상품코드 별 매출액(판매가 * 판매량) 합계를 출력하는 SQL문을 작성해주세요. 결과는 매출액을 기준으로 내림차순 정렬해주시고 매출액이 같다면 상품코드를 기준으로 오름차순 정렬해주세요.

SELECT PRODUCT_CODE,
    (PRICE * SUM(SALES_AMOUNT)) AS SALES
FROM PRODUCT AS T1
LEFT JOIN OFFLINE_SALE AS T2 ON T2.PRODUCT_ID = T1.PRODUCT_ID
GROUP BY PRODUCT_CODE
ORDER BY SALES DESC, PRODUCT_CODE ASC

프로그래머스 문제 8-3 (level 2)

상반기 아이스크림 총주문량이 3,000보다 높으면서 아이스크림의 주 성분이 과일인 아이스크림의 맛을 총주문량이 큰 순서대로 조회하는 SQL 문을 작성해주세요.

SELECT T2.FLAVOR
FROM ICECREAM_INFO AS T1
LEFT JOIN FIRST_HALF AS T2 ON T1.FLAVOR = T2.FLAVOR 
WHERE TOTAL_ORDER > 3000 AND INGREDIENT_TYPE = 'fruit_based'
GROUP BY FLAVOR
ORDER BY TOTAL_ORDER DESC

프로그래머스 문제 8-4 (level 2)

 

프로그래머스 문제 8-5 (level 3)

2022년 1월의 카테고리 별 도서 판매량을 합산하고, 카테고리(CATEGORY), 총 판매량(TOTAL_SALES) 리스트를 출력하는 SQL문을 작성해주세요.
결과는 카테고리명을 기준으로 오름차순 정렬해주세요.

SELECT CATEGORY,
SUM(SALES) AS TOTAL_SALES
FROM BOOK AS T1 
LEFT JOIN BOOK_SALES AS T2 ON T2. BOOK_ID = T1.BOOK_ID
WHERE DATE_FORMAT(SALES_DATE, '%Y-%m') = '2022-01'
GROUP BY CATEGORY
ORDER BY CATEGORY ASC

 

프로그래머스 문제 8-6 (level 3)

입양을 간 동물 중, 보호 기간이 가장 길었던 동물 두 마리의 아이디와 이름을 조회하는 SQL문을 작성해주세요. 이때 결과는 보호 기간이 긴 순으로 조회해야 합니다.

SELECT T1.ANIMAL_ID, T1.NAME
FROM ANIMAL_INS AS T1
LEFT JOIN ANIMAL_OUTS AS T2 ON T1. ANIMAL_ID = T2.ANIMAL_ID
ORDER BY T2.DATETIME - T1.DATETIME DESC
LIMIT 2

프로그래머스 문제 8-7 (level 3)

아직 입양을 못 간 동물 중, 가장 오래 보호소에 있었던 동물 3마리의 이름과 보호 시작일을 조회하는 SQL문을 작성해주세요. 이때 결과는 보호 시작일 순으로 조회해야 합니다.

SELECT T1.NAME, T1.DATETIME

FROM ANIMAL_INS AS T1 
LEFT JOIN ANIMAL_OUTS AS T2 ON T1.ANIMAL_ID = T2.ANIMAL_ID
WHERE ISNULL(T2.ANIMAL_ID)
ORDER BY T1.DATETIME
LIMIT 3

아직 입양 못 간 동물 -> WHERE ISNULL 로 찾아 줌

INNER JOIN인가 처음에 생각했는데 그럼 교집합이라 떠난 애들만 알 수 있게 

 

프로그래머스 문제 8-8 (level 3)

관리자의 실수로 일부 동물의 입양일이 잘못 입력되었습니다. 보호 시작일보다 입양일이 더 빠른 동물의 아이디와 이름을 조회하는 SQL문을 작성해주세요. 이때 결과는 보호 시작일이 빠른 순으로 조회해야합니다.

SELECT
T1.ANIMAL_ID, T1.NAME
FROM ANIMAL_INS AS T1 
LEFT JOIN ANIMAL_OUTS AS T2 ON T2.ANIMAL_ID = T1.ANIMAL_ID 

WHERE T1.DATETIME > T2.DATETIME
ORDER BY T1.DATETIME

 

프로그래머스 문제 8-9 (level 3)

천재지변으로 인해 일부 데이터가 유실되었습니다. 입양을 간 기록은 있는데, 보호소에 들어온 기록이 없는 동물의 ID와 이름을 ID 순으로 조회하는 SQL문을 작성해주세요.

SELECT T2.ANIMAL_ID, T2.NAME
FROM ANIMAL_INS AS T1 
RIGHT JOIN ANIMAL_OUTS AS T2 ON T2.ANIMAL_ID = T1.ANIMAL_ID
WHERE ISNULL(T1.ANIMAL_ID)
ORDER BY ANIMAL_ID

처음에 left join 해서 틀림 why?

left join으로 하면 animal_ins를 중심으로 join 되는 건데 유실된 기록은 t1에는 없지만 t2에는 있는 유실되지 않은 기록만 남게 됨 

right join하면 모두 다 남게 되고!

만약에 left join을 쓰고 싶으면 animal_out를 먼저 두면 됨 !

'AI SCHOOL > SQL' 카테고리의 다른 글

[SQL] 집합 연습문제  (0) 2023.01.27
[SQL] 집합  (0) 2023.01.27
[SQL] 조건분기(CASE, IF)  (0) 2023.01.26
[SQL] JOIN  (1) 2023.01.26
[SQL] 조건분기(CASE, IF) 연습문제  (1) 2023.01.26