반응형
특정 개수의 행만 조회 (rownum)
-- rownum : 조회된 행 순서대로 행 번호를 매김.
-- 무조건 1번부터 시작하며 중간에 끊어서 확인할 수 없음.
select rownum, emp.* from emp;
-- select 하는 순간에 rownum은 부여되지만 가장 마지막에 나열되는 order by로 인해 뒤직박죽으로 출력됨.
select rownum, emp.* from emp order by job;
-- 행 번호 유지시키기 위해서는 아래와 같은 방식으로 해야함.
-- rownum을 사용할 때 주로 서브쿼리를 사용한다.
-- 서브쿼리 : select 안에 select문이 있는 쿼리
select rownum, x.*
from (select a.* from emp a order by a.ename) x;
-- 영향을 미치지 않고 가장 처음에 있는 것만 찾거나 어느 등위 안에 들때 주로 사용.
select rownum, x.*
from (select a.* from emp a order by a.ename) x
where rownum <= 5;
-- cart table에서 주문 수량이 큰 것부터 순서를 매겨 주문번호, 주문수량을 조회하시오.
select rownum, x.cart_no 주문번호, x.cart_qty 주문수량
from (select * from cart order by cart_qty desc) x;
테이블 조인 (join)
1. Non-Equi Join
select prod_id 상품코드, prod_name 상품명, prod_sale 판매가
from prod
where prod_sale between 200000 and 400000
order by prod_sale desc;
2. Cartesian Product / Cross Join
: 모든 경우의 수를 전부 조회하는 것.
-- Cartesian Product
select * from lprod;
select * from prod;
-- 9 x 74 = 666
select count(*) from lprod, prod;
-- 8658
select count(*)
from lprod, prod, buyer;
위의 코드와 아래 코드의 결과는 같음.
아래를 더 권장사항으로 쓰길 권유한다.
-- Cross Join
-- 권장사항
select * from lprod cross join prod;
-- 8658
select count(*)
from lprod cross join prod cross join buyer;
3. Equi join / Inner join
: 내부 조인
-- Equi-join
select prod.prod_id 상품코드, prod.prod_name 상품명, lprod.lprod_nm 분류명
from prod, lprod
where prod.prod_lgu = lprod.lprod_gu;
-- ansi 형식
select prod.prod_id 상품코드, prod.prod_name 상품명, lprod.lprod_nm 분류명
from prod
inner join lprod on (prod.prod_lgu = lprod.lprod_gu);
-- 장바구니테이블의 2020년도 5월의 회원별 구매금액을 검색 하시오 ?
-- ( 구매금액 = 구매수량 * 판매가 )
-- ( Alias는 회원ID, 회원명, 구매금액 )
select * from member;
select * from cart;
select * from prod;
-- 일반 join 방법
select m.mem_id 회원ID, m.mem_name 회원명,sum(p.prod_sale * c.cart_qty) 구매금액
from cart c, member m, prod p
where c.cart_member = m.mem_id
and c.cart_prod = p.prod_id
and substr(c.cart_no, 0, 6) = '202005'
group by m.mem_id, m.mem_name;
-- inner join
select mem_id 회원ID, mem_name 회원명,sum(prod_sale * cart_qty) 구매금액
from cart
inner join member on (cart_member = mem_id)
inner join prod on (cart_prod = prod_id)
where substr(cart_no, 0, 6) = '202005'
group by mem_id, mem_name;
4. Outer join
: 외부 조인을 말하며 종류가 여러개 존재한다.
하단은 테이블과 데이터를 추가적으로 삽입하여 테스트한다.
더보기
-- 테이블 생성 및 데이터 삽입
create table a
(no number(3) not null,
name varchar2(20) not null,
constraint pk_a primary key(no));
create table b
(no number(3) not null,
score number(3) not null,
constraint pk_b primary key(no));
insert into a values(1, '김철수');
insert into a values(2, '박미미');
insert into a values(3, '정다비');
insert into a values(4, '멘토스');
insert into a values(5, '박버거');
insert into b values(1, 60);
insert into b values(2, 71);
insert into b values(5, 99);
insert into b values(7, 100);
- left outer join
-- outer join
-- left outer join : 아무것도 없는 값은 null을 뿌려줌
-- where r.c = s.c(+);
select * from a, b where a.no = b.no(+);
select * from a left outer join b on (a.no = b.no);
- right outer join
-- right outer join
select * from a, b where a.no(+) = b.no;
select * from a right outer join b on (a.no = b.no);
- full outer join
-- full outer join : a와 b의 합집합
select * from a full outer join b on (a.no = b.no);
select * from a, b where a.no = b.no(+)
union
select * from a, b where a.no(+) = b.no;
- > 응용1
-- 전체 분류의 상품자료 수를 검색 조회
-- 분류코드, 분류명, 상품자료수
select * from lprod;
-- 일반 join과 inner join의 경우 상품 자료수가 있는 것만 보여짐.
-- 일반 join
select lprod_gu 분류코드, lprod_nm 분류명, count(prod_lgu) 상품자료수
from lprod, prod
where lprod_gu = prod_lgu
group by lprod_gu, lprod_nm;
-- inner join
select lprod_gu 분류코드, lprod_nm 분류명, count(prod_lgu) 상품자료수
from lprod inner join prod on (lprod_gu = prod_lgu)
group by lprod_gu, lprod_nm;
-- 전체 분류의 상품자료 수를 검색 조회
-- 분류코드, 분류명, 상품자료수
select * from lprod;
-- (left) outer join과 ansi (left) outer joi의 경우 상품 자료수가 없어도 다 보여짐.
-- (left) outer join 사용
select lprod_gu 분류코드, lprod_nm 분류명, count(prod_lgu) 상품자료수
from lprod, prod
where lprod_gu = prod_lgu(+)
group by lprod_gu, lprod_nm
order by lprod_gu;
-- ansi (left) outer join 사용 확인
select lprod_gu 분류코드, lprod_nm 분류명, count(prod_lgu) 상품자료수
from lprod left outer join prod on (lprod_gu = prod_lgu)
group by lprod_gu, lprod_nm
order by lprod_gu;
=> 상품 자료수에 상관 없이 모든 상품이 화면에 보이기 위해 사용됨.
- > 응용2
-- 전체상품의 2020년 1월 입고수량을 검색 조회
-- 상품코드, 상품명, 입고수량
-- 일반 join
select prod.prod_id 상품코드, prod.prod_name 상품명, sum(buyprod.buy_qty) 입고수량
from prod, buyprod
where prod.prod_id = buyprod.buy_prod
and buy_date between '2020-01-01' and '2020-01-31'
group by prod.prod_id, prod.prod_name;
-- outer join
-- 아래와 같은 식으로 진행 시 오류가 발생함. => 서브쿼리나 ansi 조인을 사용해야 함.
select prod.prod_id 상품코드, prod.prod_name 상품명, sum(buyprod.buy_qty) 입고수량
from prod left outer join buyprod on(prod.prod_id = buyprod.buy_prod)
group by prod.prod_id, prod.prod_name
having buyprod.buy_date between '2020-01-01' and '2020-01-31'
group by prod.prod_id, prod.prod_name;
-- 전체상품의 2020년 1월 입고수량을 검색 조회
-- 상품코드, 상품명, 입고수량
-- ansi outer join
-- 입고되지 않은 현황도 확인하기 위해 아래와 같이 사용함.
select * from prod; -- 74개
select * from buyprod; -- 148개
select prod.prod_id "상품코드", prod.prod_name 상품명, sum(buyprod.buy_qty) 입고수량
from prod left outer join buyprod on (prod.prod_id = buyprod.buy_prod
and buyprod.buy_date between '2020-01-01' and '2020-01-31')
group by prod.prod_id, prod.prod_name
order by prod.prod_id, prod.prod_name;
-- 전체상품의 2020년 1월 입고수량을 검색 조회
-- 상품코드, 상품명, 입고수량
-- null로 나오는 값을 0으로 변경해줌.
select prod.prod_id "상품코드", prod.prod_name 상품명, sum(nvl(buyprod.buy_qty, 0)) 입고수량
from prod left outer join buyprod on (prod.prod_id = buyprod.buy_prod
and buyprod.buy_date between '2020-01-01' and '2020-01-31')
group by prod.prod_id, prod.prod_name
order by prod.prod_id, prod.prod_name;
-- 전체 회원의 2020년도 4월의 구매현황 조회
-- 회원id, 성명, 구매수량의 합
-- outer join 사용
select member.mem_id 회원ID, member.mem_name 성명, sum(cart.cart_qty) 구매수량
from member right outer join cart on(member.mem_id = cart.cart_member)
and substr(cart.cart_no, 1, 6) = '202004'
group by member.mem_id, member.mem_name
order by member.mem_id, member.mem_name;
- > 응용3
-- 전체 상품의 2020년도 5월 5일의 입고, 출고현황 조회
-- 상품코드, 상품명, 입고수량의 합, 판매수량의 합
-- 입고 확인 (Equi Join)
select prod.prod_id 상품코드, prod.prod_name 상품, sum(buyprod.buy_qty) 입고수량
from prod, buyprod
where prod.prod_id = buyprod.buy_prod
and buyprod.buy_date = '20200505'
group by prod.prod_id, prod.prod_name;
-- 전체 상품의 2020년도 5월 5일의 입고, 출고현황 조회
-- 상품코드, 상품명, 입고수량의 합, 판매수량의 합
-- 출고 확인 (Inner Join)
select * from cart;
-- 위의 cart_no가 년도와 날짜 + 다른 코드 이기에 like를 사용함.
select prod.prod_id 상품코드, prod.prod_name 상품, sum(cart.cart_qty) 판매수량
from prod inner join cart on (prod.prod_id = cart.cart_prod)
where cart.cart_no like '20200505%'
group by prod.prod_id, prod.prod_name;
- > 입고 출고를 한 번에 보기 위해 아래와 같은 방식을 사용함.
-- 전체 상품의 2020년도 5월 5일의 입고, 출고현황 조회
-- 상품코드, 상품명, 입고수량의 합, 판매수량의 합
-- outer join 사용 확인
-- null 값 제거
select prod.prod_id 상품코드, prod.prod_name 상품, sum(nvl(buyprod.buy_qty, 0)) 입고수량, sum(nvl(cart.cart_qty, 0)) 판매수량
from prod
left outer join buyprod on(prod.prod_id = buyprod.buy_prod and buyprod.buy_date = '20200505')
left outer join cart on (prod.prod_id = cart.cart_prod and substr(cart.cart_no, 1, 8) = '20200505')
having sum(nvl(buyprod.buy_qty, 0)) > 0 or sum(nvl(cart.cart_qty, 0)) > 0
group by prod.prod_id, prod.prod_name;
정리
select * from a;
select * from b;
-- 1. inner join
select * from a inner join b on a.no = b.no;
select * from a, b where a.no = b.no;
-- 2. left outer join
select * from a left outer join b on(a.no = b.no);
select * from a, b where a.no = b.no(+);
-- 3. right outer join
select * from a right outer join b on(a.no = b.no);
select * from a, b where a.no(+) = b.no;
-- 4. full outer join
select * from a full outer join b on(a.no = b.no);
select * from a, b where a.no(+) = b.no
union
select * from a, b where a.no = b.no(+);
4. Self join
-- self join
select b.mem_id 회원ID, b.mem_name 성명, b.mem_mileage 마일리지
from member a, member b
where a.mem_id = 'h001'
and a.mem_mileage <= b.mem_mileage;
group by의 조건절 (having)
-- having 절 정리
-- 2020년도 판매일자, 판매총액 (5,000,000초과의 경우만),
-- 판매수량 (50초과의 경우만), 판매횟수를 조회하시오.
-- 단, 판매회수가 8개 이상인 판매일자만 조회
select * from prod;
select * from cart;
select substr(cart.cart_no, 1, 8) 판매일, sum(cart.cart_qty * prod.prod_sale) 판매금액, sum(cart.cart_qty) 판매수량, count(*) 판매횟수
from prod inner join cart on(prod.prod_id = cart.cart_prod)
where cart.cart_no like '2020%'
group by substr(cart.cart_no, 1, 8)
having sum(cart.cart_qty * prod.prod_sale) > 5000000
and sum(cart.cart_qty) > 50
and count(*) >= 8
order by substr(cart.cart_no, 1, 8);
반응형
'데이터베이스' 카테고리의 다른 글
[Database] 15장 서브쿼리 (0) | 2023.12.28 |
---|---|
[Database] 14장 SQL 연습문제4 (2) | 2023.12.27 |
[Database] 12장 함수 모음1 (0) | 2023.12.22 |
[Database] 11장 날짜 타입 (0) | 2023.12.19 |
[Database] 10장 SQL 연습문제3 (0) | 2023.12.19 |