[SQL 4주차] Subquery

Subquery란?

하나의 SQL 쿼리 안에 또 다른 SQL 쿼리가 있는 것.

ex)

  • kakaopay로 결제한 유저들의 정보보기
//기존//
select u.user_id, u.name, u.email from user u
inner join orders o on u.user_id = o.user_id
where o.payment_method = 'kakaopay'

//서브쿼리//
select u.user_id, u.name, u.email from users u
where u.user_id in (
	select user_id from orders
    where payment_method = 'kakaopay'
    )
  • subquery 유형
    : where, select, from 절에서 유용하게 사용.

where절

연습

  • where 절에 들어가는 Subquery 연습
    1) 전체 유저의 포인트 평균보다 큰 유저들의 데이터 추출

2) 이씨 성을 가진 유저의 포인트의 평균보다 큰 유저들의 데이터 추출하기

SELECT * FROM point_users pu 
WHERE point > (
	SELECT avg(`point`) FROM point_users pu 
	WHERE pu.user_id in (
	select u.user_id FROM users u 
	WHERE u.name = '이**'
)   // subquery 안에 또 subquery가 들어갈 수 있음.
SELECT * FROM point_users pu 
WHERE point > (
	SELECT avg(point) FROM point_users pu 
inner join users u on pu.user_id = u.user_id 
where u.name = '이**'
)
  • select 절에 들어가는 subquery 연습
SELECT c.checkin_id, 
	   c.course_id, 
	   c.user_id, 
	   c.likes ,
 	   (
 	   select avg(likes) FROM checkins 
 	   WHERE course_id = c.course_id 
 	   ) as course_avg
 FROM checkins c 
 
 
SELECT c.checkin_id, 
	   c2.title, 
	   c.user_id, 
	   c.likes ,
 	   (
 	   select round(avg(likes),1) FROM checkins 
 	   WHERE course_id = c.course_id 
 	   ) as course_avg
 FROM checkins c 
inner join courses c2 on c.course_id = c2.course_id  
  • from 절에 들어가는 subquery 연습
SELECT a.course_id, 
	   a.cnt_checkins, 
	   b.cnt_total,
	   (a.cnt_checkins/b.cnt_total) as ratio
	   FROM 
(
	SELECT course_id, count(distinct(user_id)) as cnt_checkins FROM  checkins c 
	group by course_id 
) a
inner JOIN 
(
	SELECT course_id, count(*) as cnt_total FROM orders o 
	group by course_id 
) b on a.course_id = b.course_id
inner join courses c on a.course_id = c.course_id 

with 절 연습

with table1 as (
	select course_id, count(distinct(user_id)) as cnt_checkins from checkins
	group by course_id
), table2 as (
	select course_id, count(*) as cnt_total from orders
	group by course_id 
)

select c.title,
       a.cnt_checkins,
       b.cnt_total,
      (a.cnt_checkins/b.cnt_total) as ratio
from table1 a inner join table2 b on a.course_id = b.course_id
inner join courses c on a.course_id = c.course_id

문자열 데이터

문자열 쪼개기 : SUBSTRING_INDEX

select user_id, email, SUBSTRING_INDEX(email, '@', 1) from users
 => @를 기준으로 쪼개고, 그 중 첫번째 조각을 가져오라

문자열 일부만 출력하기 : SUBSTRING

select order_no, created_at, substring(created_at,1,10) as date from orders
=> substting(문자열, 출력하고싶은첫글자위치, 출력하고싶은문자개수)

Case

: 원하는 값을 새 필드에 출력해보기

좋은 웹페이지 즐겨찾기