서브쿼리(sub Query)
- 다른 쿼리 내부에 포함되어 있는 select 문을 의미
- 서브쿼리를 포함하고 있는 쿼리를 외부쿼리라고 부르고, 서브쿼리는 내부쿼리라고도 부름
- 서브쿼리는 괄호()로 감싸져서 표현
- 서브쿼리는 메인쿼리 컬럼 사용이 가능, 메인쿼리는 서브쿼리 컬럼을 사용하지 못함
- 서브쿼리는 select, where, from, having 절 등에서 사용할 수 있음
where 절
# 100001의 가격보다 크거나 같은 price를 가지고 있는 상품의 모든 정보
select * from product where price >= (select price from product where code = '100001');
code |
name |
detail |
price |
regdate |
100000 |
아이폰14 |
이뻐요 |
1500000 |
2023-03-20 11:42:26 |
100001 |
갤럭시23 |
좋아요 |
1300000 |
2023-03-20 11:42:27 |
100002 |
맥북에어 |
가벼워요 |
1400000 |
2023-03-20 11:42:28 |
100003 |
z플립4 |
잘접혀요 |
1800000 |
2023-03-20 11:42:28 |
select 절
# 코드, 이름, 가격, 전체 데이터의 가격중 가장 큰 값을 출력하는 쿼리
select code, name, price, (select max(price) as 최대값 from product) as 최대값 from product;
code |
name |
price |
최대값 |
100000 |
아이폰14 |
1500000 |
1800000 |
100001 |
갤럭시23 |
1300000 |
1800000 |
100002 |
맥북에어 |
1400000 |
1800000 |
100003 |
z플립4 |
1800000 |
1800000 |
100004 |
LG공기청정기 |
600000 |
1800000 |
create table orders(
no int not null,
userid varchar(20) not null,
product varchar(100) not null,
cnt int default 1,
regdate datetime default now(),
foreign key(userid) references member(userid)
);
insert into orders (no, userid, product, cnt) values(1, 'apple', '사과', 3);
insert into orders (no, userid, product, cnt) values(2, 'apple', '꿀사과', 2);
insert into orders (no, userid, product, cnt) values(3, 'banana', '바나나', 5);
insert into orders (no, userid, product, cnt) values(4, 'banana', '딸바', 1);
insert into orders (no, userid, product, cnt) values(5, 'orange', '오렌지', 2);
insert into orders (no, userid, product, cnt) values(6, 'berry', '블루베리', 3);
# 상품을 최소 2개이상 구입한 회원의 id, 이름, 성별을 출력
select userid, username, gender from member where userid in (select userid from orders group by userid having count(no) >= 2);
userid |
username |
gender |
apple |
김사과 |
남자 |
banana |
반하나 |
남자 |
# 상품을 2번이상 구입한 사용자의 아이디, 상품 구입횟수, 시도 이름을 출력
# 조인 사용
select m.userid, count(o.no) as cnt, substring(m.address, 1, 3) as address
from member as m right outer join orders as o on m.userid = o.userid group by userid having cnt >= 2;
userid |
cnt |
address |
apple |
2 |
서울시 |
banana |
2 |
경기도 |
# from절
select m.userid, t.ocnt, substring(m.address, 1, 3) as address from member as m
right outer join
(select userid, count(no) as ocnt from orders group by userid having count(no) >= 2) as t on m.userid = t.userid;
userid |
ocnt |
address |
apple |
2 |
서울시 |
banana |
2 |
경기도 |
create table orders2(
no int not null,
userid varchar(20) not null,
product varchar(100) not null,
cnt int default 1,
regdate datetime default now(),
foreign key(userid) references member(userid)
);
# orders와 동일한 테이블 orders2를 만들고 orders에 존재하는 데이터를 모두 복사하여 orders2에 저장
insert into orders2(select * from orders);
select * from orders2;
no |
userid |
product |
cnt |
regdate |
1 |
apple |
사과 |
3 |
2023-03-20 13:42:02 |
2 |
apple |
꿀사과 |
2 |
2023-03-20 13:42:03 |
3 |
banana |
바나나 |
5 |
2023-03-20 13:42:03 |
4 |
banana |
딸바 |
1 |
2023-03-20 13:42:04 |
5 |
orange |
오렌지 |
2 |
2023-03-20 13:42:05 |
6 |
berry |
블루베리 |
3 |
2023-03-20 13:42:06 |
# orders와 동일한 형태의 테이블 생성
create table orders3(select * from orders);
select * from orders3;
no |
userid |
product |
cnt |
regdate |
1 |
apple |
사과 |
3 |
2023-03-20 13:42:02 |
2 |
apple |
꿀사과 |
2 |
2023-03-20 13:42:03 |
3 |
banana |
바나나 |
5 |
2023-03-20 13:42:03 |
4 |
banana |
딸바 |
1 |
2023-03-20 13:42:04 |
5 |
orange |
오렌지 |
2 |
2023-03-20 13:42:05 |
6 |
berry |
블루베리 |
3 |
2023-03-20 13:42:06 |