[Oracle] 오라클 - 조인 (INNER JOIN 종류 / EQUI JOIN 등)
by mini_min[Oracle]
오라클 - 조인 (INNER JOIN 종류 / EQUI JOIN 등)
✔️ 조인(joins)
: 둘 이상의 테이블, 뷰의 행을 결합하는 쿼리다.
: 쿼리의 FROM 절에 여러 테이블이 나타날 때마다 조인을 수행한다.
: 선택 목록은 이러한 테이블에서 컬럼을 선택할 수 있다.
: 조인된 두 테이블에서 하나의 공통된 컬럼 이름이 있으면, 모호성 피하기 위해 테이블 이름을 정확하게 명시해야한다.
❌ 명확하게 테이블 이름 명시하지 않으면 모호한 컬럼 이름이라고 실행안됨
❤️ 조인 조건
: FROM 또는 WHERE 절에 조인 조건이 포함된다.
✔️ INNER JOIN
: 조건에 만족하는 행만 반환하며, 둘 이상의 테이블을 조인한다.
ex) 테이블
-- 분류 테이블(분류코드, 분류명, 상위분류코드)
SELECT bcCode, bcSubject, pcCode FROM bclass;
-- 출판사 테이블(출판사번호, 출판사명, 전화번호)
SELECT pNum, pName, pTel FROM pub;
-- 책 테이블(서적코드, 서적명, 가격, 분류코드, 출판사번호)
SELECT bCode, bName, bPrice, bcCode, pNum FROM book;
-- 저자 테이블(저자번호, 서적코드, 저자명)
SELECT aNum, bCode, aName FROM author;
-- 고객 테이블(고객번호, 고객명, 전화번호)
SELECT cNum, cName, cTel FROM cus;
-- 회원 테이블(고객번호, 회원아이디, 회원패스워드, 이메일)
SELECT cNum, userId, userPwd, userEmail FROM member;
-- 판매 테이블(판매번호, 판매일자, 고객번호)
SELECT sNum, sDate, cNum FROM sale;
-- 판매 상세 테이블(판매상세번호, 판매번호, 서적코드, 판매수량)
SELECT dNum, sNum, bCode, qty FROM dsale;
✔️ EQUI JOIN
: 조건에 정확하게! 일치하는 경우에만 조인한다.
기본적으로 조인은 테이블에 별명을 주는 것이 편하다.
'=' 을 통해 주는 조인!
-- 기본형식
SELECT [테이블명1.]컬럼명, [테이블명2.]컬럼명 ....
FROM 테이블명1, 테이블명2
WHERE 테이블명1.컬럼명 = 테이블명2.컬럼명 [AND 조건]
--2번째 형식
SELECT [테이블명1.]컬럼명, [테이블명2.]컬럼명 ....
FROM 테이블명1
[ INNER ] JOIN 테이블명2 ON 테이블명1.컬럼명 = 테이블명2.컬럼명
💡 FROM 에 여러 테이블을 주는 것보다, 2번째 형식처럼 기준되는 테이블 하나를 FROM 에 두고 나머지는 (INNER) JOIN 으로 사용하는게 좋다.
❌ USING 사용하는 형식도 있는데, 별로 권하지 않는다고 함
SELECT b.bCode, bName, bPrice, b.pNum, pName, sDate, s.cNum, cName, qty, bPrice * qty
FROM book b
JOIN pub p ON b.pNum = p.pNum
JOIN dsale d ON b.bCode = d.bCode
JOIN sale s ON d.sNum = s.sNum
JOIN cus c ON c.cNum = s.cNum;
🔒 문제
-- 고객명:서울서점의 판매현황
-- BOOK / PUB / sale / cus / dsale / (book 이랑 dsale)
-- 책코드 , 책이름, 책가격, 출판사명, 판매일자, 고객번호, 고객이름, 수량, 금액(수량*단가)
SELECT b.bCode, b.bName, p.pName, s.sDate, c.cNum, c.cName, qty, (qty*bPrice) amt
FROM book b
JOIN pub p ON b.pNum = p.pNum
JOIN dsale d ON d.bCode = b.bCode
JOIN sale s ON d.sNum = s.sNum
JOIN cus c ON s.cNum = c.cNum
WHERE cName = '서울서점';
💡 조인 한 뒤, WHERE 절로 조건 줄 수도 있음!
테이블 명 명시잘해야한다 ㅜㅜ
book 테이블을 가지고 연결... 연결해서 조인하기
-- 판매된 책코드(bCode), 책이름(bName), 판매권수합이 80권 이상
SELECT b.bCode, bName, SUM(qty) 판매수량합
FROM book b
JOIN dsale d ON b.bCode = d.bCode
GROUP BY b.bCode, bName
HAVING SUM(*) >= 80
ORDER BY bCode;
-- 판매된 책코드(bCode), 책이름(bName) : 중복배제
SELECT DISTINCT b.bCode, bName
FROM book b
JOIN dsale d ON b.bCode = d.bCode
💡 DISTINCT 를 쓰거나 unique 를 사용해서 중복도 배제할 수 있다.
⭐-- (랭킹 함수 사용) 판매 권수 합이 가장 많이 판매된 책
SELECT bCode, bName FROM(
SELECT b.bCode, bName, SUM(qty) 판매수량합, RANK()OVER(ORDER BY SUM(qty)DESC) 랭킹
FROM book b
JOIN dsale d ON b.bCode = d.bCode
GROUP BY b.bCode, bName
ORDER BY 판매수량합 DESC
) WHERE 랭킹 = 1;
💡 서브쿼리 안에서 랭킹을 구하고, 밖에 있는 SELECT 절에서 랭킹 구하기 가능!
만약, 1~5등 까지 출력하고 싶으면, IN 사용해서 답 구하기
🔒 문제 - 2
-- 올해의 판매 현황
-- BOOK / PUB / sale / cus / dsale / (book 이랑 dsale)
-- 책코드 , 책이름, 책가격, 출판사명, 판매일자, 고객번호, 고객이름, 수량, 금액(수량*단가)
SELECT b.bCode, b.bName, p.pName, s.sDate, c.cNum, c.cName, qty, (qty*bPrice) amt
FROM book b
JOIN pub p ON b.pNum = p.pNum
JOIN dsale d ON d.bCode = b.bCode
JOIN sale s ON d.sNum = s.sNum
JOIN cus c ON s.cNum = c.cNum
WHERE TO_CHAR(SYSDATE, 'YYYY') = TO_CHAR(sDate, 'YYYY');
💡 이번 달 판매 현황이 궁금하다면,
TO_CHAR(sDate, 'MM') 으로 비교하기!
작년 판매 현황이 궁금하다면,
WHERE TO_CHAR(SYSDATE - (INTERVAL '1' YEAR), 'YYYY') = TO_CHAR(sDate, 'YYYY');
-- 년도별 판매 현황
SELECT TO_CAHR(sDate, 'YYYY'), SUM(qty*bPrice)
FROM book b
JOIN dsale d ON b.bCode = d.bCode
JOIN sale s ON d.sNum = s.sNum
GROUP BY TO_CAHR(sDate, 'YYYY');
-- 지난 달 고객번호, 고객명, 판매금액 합 ⭐⭐ 인터벌 불가
SELECT c.cNum, c.cName, TO_CHAR(sDate, 'YYYY-MM') 년도, SUM(qty*bPrice) 판매금액합
FROM book b
JOIN dsale d ON b.bCode = d.bCode
JOIN sale s ON d.sNum = s.sNum
JOIN cus c ON c.cNum = s.cNum
WHERE TO_CHAR(sDate, 'YYYYMM') = TO_CHAR(ADD_MONTHS(SYSDATE, -1), 'YYYYMM')
GROUP BY c.cNum, c.cName, TO_CHAR(sDate, 'YYYY-MM')
ORDER BY c.cNum, 년도;
💡MONTH 는 인터벌로 비교하면 예상치 못한 오류가 발생하는 경우가 많음.
그래서 MONTH 계산할 때는 ADD_MONTHS 또는 MONTHS_BETWEEN 같은 함수 사용하는게 좋음
✔️ NATURAL JOIN
: 중복을 없애고 한 번씩만 나오게 하는 조인이다.
(거의 조인할 일이 없다고 함!)
-- 기본형식
SELECT 컬럼명, 컬럼명 ....
FROM 테이블명1
NATURAL JOIN 테이블명2
✔️ CROSS JOIN
: 카디션 곱 (곱한 갯수만큼 결과가 나온다.)
(마찬가지로 거의 조인할 일이 없다고 한다.)
-- 예시
SELECT p.pNum, pName, bCode, bName
FROM pub p
CROSS JOIN book b;
'SQL쿼리' 카테고리의 다른 글
[Oracle] 오라클 - 제약조건 확인 / 부자 관계 출력 / 부모 테이블, 자식 테이블 목록 (0) | 2022.08.13 |
---|---|
[Oracle] 오라클 - 셀프 조인 / NON-EQUI JOIN (0) | 2022.08.11 |
[Oracle] 오라클 - 참조 키(외래 키, FOREIGN KEY) / 참조 키 관계 (0) | 2022.08.10 |
[Oracle] 오라클 - UNIQUE 제약 조건 / NOT NULL 제약 조건 / DEFAULT (0) | 2022.08.10 |
[Oracle] 오라클 - 데이터 제약 조건 / 기본키 설정 (0) | 2022.08.10 |
블로그의 정보
개발자 미니민의 개발로그
mini_min