Subquery☆
큰 쿼리 안에 들어가있는 쿼리문
SELECT u.user_id, u.name, u.email from users 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 user_id in (
select user_id from orders o
where payment_method = 'kakaopay'
)
1. Where (중첩 서브쿼리)
형태 : Where 필드명 in (subquery)
가장 일반적인 서브쿼리로, A 테이블의 X 데이터와 B 테이블의 X 데이터를 조회
--ex) point_users와 users를 이용하여 이씨 성을 가진 유저의 평균 보인트보다 큰 유저들의 데이터 추출
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 * from point_users pu
WHERE point > (
SELECT * from point_users pu
WHERE user_id in (
select user_id from users u where u.name = '이**'
)
)
2. Select
형태 : select 필드명, 필드명, (subquery) from
select절에 사용되는 서브쿼리로, 하나의 상수 또는 Join을 대체하기 위한 용도. 하나의 열처럼 사용.
/*ex) checkins에 course를 Join하고 checkin_id, user_id, title, likes, course_avg를 출력하세요.
course_avg는 course_id별 좋아요의 평균값임*/
SELECT ch.checkin_id,
ch.user_id,
c.title,
ch.likes,
(
select ROUND(AVG(likes),1) from checkins ch2
WHERE ch2.course_id = ch.course_id
) as course_avg
from checkins ch
inner join courses c on ch.course_id = c.course_id
3. From
형태 : select * from ( select * from ) 테이블명
하나의 테이블처럼 사용. 열 이름을 반드시 명시해야 함.
/*ex) checkins와 orders의 course_id별 중복 없이 유저의 체크인 개수를 구하고,
course의 title과 course_id, cnt_checkins, cnt_total, ratio(비율)*/
SELECT c2.title,
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 c.course_id
) a
inner join (
SELECT course_id, count(DISTINCT(user_id)) as cnt_total from orders o
group by o.course_id
) b on a.course_id = b.course_id
inner join courses c2 on a.course_id = c2.course_id
With 절
제일 윗단에 작성. 임시 테이블 같은 역할.
with table1 as (
SELECT course_id, COUNT(DISTINCT(user_id)) as cnt_checkins from checkins c
group by c.course_id
), table2 as (
SELECT course_id, count(DISTINCT(user_id)) as cnt_total from orders o
group by o.course_id
)
SELECT c2.title,
a.course_id,
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 c2 on a.course_id = c2.course_id
/*위의 from문과 같음. with문이 더 명시적이라는 장점*/
실전 SQL 문자열
1. substring_index (문자 쪼개기)
SELECT user_id, email, SUBSTRING_INDEX(email,'@',-1) from users u
-- 1은 첫번째, -1은 마지막 것을 보여줌
2. substring (문자열 일부만 출력)
--ex) 날짜의 일부(시간 생략)만 출력해 주문 개수 세기
SELECT SUBSTRING(created_at, 1, 10) as date, COUNT(*) as total from orders o
group by date
'SQL' 카테고리의 다른 글
Case when문 (0) | 2023.02.27 |
---|---|
Join과 Union (0) | 2023.02.23 |
Group by, Order by, Alias 3일차 (0) | 2023.02.22 |
조건문 Where와 추가문법 2일차 (0) | 2023.02.21 |
조건문 Where 기초 (1일차) (0) | 2023.02.20 |