조인(JOIN)
- 필요한 데이터가 여러 테이블에 분산되어 있고 각 테이블 들이 관계를 맺고 있을 때 수행하는 연산
- 관계(RELATIONSHIP)을 이용한 연산
- 구분
. 조인연산자에 따라 동등조인(Equi Join), 비동등 조인(Non Equi Join)
. 조인 대상에 따라 : 셀프조인(Self Join)
. 조인 조건에 따라 : 내부조인(Inner Join), 외부조인(Outer Join), 카타시안(Cartasian, Cross Join), 세미조인(Semi Join)
. 기타 : ANSI Join
1. 내부조인
- 조인조건을 만족하는 행만 결과로 반환하고 조인조건을 만족하지 않는 데이터는 무시함.
1) 카타시안(Cartesian Product, Cross Join)
- 조인조건이 없거나 조인조건을 잘못기술한 경우
- 반드시 필요한 경우가 아니면 수행하지 말아야 함
- A(a행 b열), B(c행 d열) 두 테이블에 카타시안 조인을 수행하면
결과는 최악의 경우(조인조건이 없는 경우) a * c 행 b + d열이 반환
사용예)
SELECT COUNT(*) FROM BUYPROD; -- 매입테이블의 모든 행의 수
SELECT COUNT(*) FROM CART; -- 매출테이블의 모든 행의 수
SELECT COUNT(*) FROM PROD; -- 상품테이블의 모든 행의 수
SELECT 148*207*74 FROM DUAL;
1-2) CROSS JOIN
. ANSI에서 제공하는 Cartesian Product
(사용형식)
SELECT 컬럼list
FROM 테이블명1 [별칭1]
CROSS JOIN 테이블명2 [별칭2] [ON(조인조건)]
:
CROSS JOIN 테이블명n [별칭n] [ON(조인조건)]
사용예)
SELECT COUNT(*)
FROM BUYPROD A
CROSS JOIN CART B
CROSS JOIN PROD C;
2) 동등조인(Equi Join)
- 조인조건문에 사용하는 연산자가 '='인 조인
(사용형식:일반 조인)
SELECT [테이블별칭.|테이블명.]컬럼명 [AS 컬럼별칭][,]
:
[테이블별칭.|테이블명.]컬럼명 [AS 컬럼별칭]
FROM 테이블명1 [별칭1], 테이블명2 [별칭2], [,테이블명3 [별칭3],...]
WHERE 조인조건
[AND 일반조건]
- '테이블별칭|테이블명.' : 모든 컬럼명이 다르면 생략 가능
-- 중요!! 조인 조건의 갯수가 n-1보다 적으면 문제가 된다.
- 사용된 테이블의 갯수가 n개일 때 '조인조건'의 갯수는 적어도 n-1개 이상이어야 함
(사용형식:ANSI INNER 조인)
SELECT [테이블별칭.|테이블명.]컬럼명 [AS 컬럼별칭][,]
:
[테이블별칭.|테이블명.]컬럼명 [AS 컬럼별칭]
FROM 테이블1 [별칭1]
INNER JOIN 테이블2 [별칭2] ON(조인조건 [AND 일반조건])
INNER JOIN 테이블3 [별칭3] ON(조인조건 [AND 일반조건])
:
[WHERE 일반조건]
- 테이블1과 테이블2는 반드시 직접 조인 가능해야 함
- '[AND 일반조건]' : 해당 테이블에만 적용되는 조건 기술
- 'WHERE 일반조건' : 공통으로 적용된 일반조건 기술
- 테이블1과 테이블2가 조인된 결과와 테이블3이 조인됨
사용예) 사원테이블에서 20-40번 부서에 소속된 사원의 사원번호,사원명,부서번호,부서명,직무명을 조회하시오
(일반 조인문)
SELECT A.EMPLOYEE_ID AS 사원번호,
A.EMP_NAME AS 사원명,
B.DEPARTMENT_ID AS 부서번호,
B.DEPARTMENT_NAME AS 부서명,
C.JOB_TITLE AS 직무명
FROM HR.EMPLOYEES A, HR.DEPARTMENTS B, HR.JOBS C
WHERE A.DEPARTMENT_ID=B.DEPARTMENT_ID -- 조인조건
AND A.JOB_ID=C.JOB_ID -- 조인조건
AND A.DEPARTMENT_ID BETWEEN 20 AND 40 -- 일반조건
ORDER BY 3;
(ANSI JOIN)
SELECT A.EMPLOYEE_ID AS 사원번호,
A.EMP_NAME AS 사원명,
B.DEPARTMENT_ID AS 부서번호,
B.DEPARTMENT_NAME AS 부서명,
C.JOB_TITLE AS 직무명
FROM HR.EMPLOYEES A
INNER JOIN HR.DEPARTMENTS B ON(A.DEPARTMENT_ID=B.DEPARTMENT_ID) -- 조인조건
INNER JOIN HR.JOBS C ON(A.JOB_ID=C.JOB_ID) -- 조인조건
WHERE A.DEPARTMENT_ID BETWEEN 20 AND 40
ORDER BY 3;
사용예) 2020년 4월 상품별 매출집계를 조회하시오. Alias는 상품코드,상품명,매출수량합계,매출금액합계
(일반 조인문)
SELECT A.CART_PROD AS 상품코드,
B.PROD_NAME AS 상품명,
SUM(A.CART_QTY) AS 매출수량합계,
SUM(A.CART_QTY*B.PROD_PRICE) AS 매출금액합계
FROM CART A, PROD B
WHERE A.CART_PROD=B.PROD_ID -- 조인조건
AND A.CART_NO LIKE '202004%'
GROUP BY A.CART_PROD,B.PROD_NAME
ORDER BY 1;
(ANSI 조인)
SELECT A.CART_PROD AS 상품코드,
B.PROD_NAME AS 상품명,
SUM(A.CART_QTY) AS 매출수량합계,
SUM(A.CART_QTY*B.PROD_PRICE) AS 매출금액합계
FROM CART A
INNER JOIN PROD B ON(A.CART_PROD=B.PROD_ID) -- 조인조건
WHERE A.CART_NO LIKE '202004%'
GROUP BY A.CART_PROD,B.PROD_NAME
ORDER BY 1;
사용예) 2020년 1-6월 거래처별 매입집계를 조회하시오. Alias는 거래처코드,거래처명,매입금액 합계
(일반 조인문)
SELECT A.BUYER_ID AS 거래처코드,
A.BUYER_NAME AS 거래처명,
SUM(B.BUY_QTY*C.PROD_COST) AS "매입금액 합계"
FROM BUYER A, BUYPROD B, PROD C
WHERE B.BUY_PROD=C.PROD_ID -- 조인조건
AND C.PROD_BUYER=A.BUYER_ID -- 조인조건
AND B.BUY_DATE BETWEEN TO_DATE('20200101') AND TO_DATE('20200630')
GROUP BY A.BUYER_ID, A.BUYER_NAME
ORDER BY 1;
(ANSI FORMAT)
SELECT A.BUYER_ID AS 거래처코드,
A.BUYER_NAME AS 거래처명,
SUM(B.BUY_QTY*C.PROD_COST) AS "매입금액 합계"
FROM BUYER A
INNER JOIN PROD C ON(C.PROD_BUYER=A.BUYER_ID) -- 조인조건
INNER JOIN BUYPROD B ON(B.BUY_PROD=C.PROD_ID) -- 조인조건
WHERE B.BUY_DATE BETWEEN TO_DATE('20200101') AND TO_DATE('20200630')
GROUP BY A.BUYER_ID, A.BUYER_NAME
ORDER BY 1;
문제] HR계정에서 미국 이외의 국가에 있는 부서에 근무하는 사원들을 조회하시오. Alias는 사원번호,사원명,부서코드,부서명,부서주소 (미국의 국가코드는 'US')
(일반 조인문)
SELECT A.EMPLOYEE_ID AS 사원번호,
A.EMP_NAME AS 사원명,
B.DEPARTMENT_ID AS 부서코드,
B.DEPARTMENT_NAME AS 부서명,
C.STREET_ADDRESS||' '||C.CITY||' '||C.STATE_PROVINCE||', '||
D.COUNTRY_NAME AS 부서주소,
D.COUNTRY_ID AS 국가코드
FROM HR.EMPLOYEES A, HR.DEPARTMENTS B, HR.LOCATIONS C, HR.COUNTRIES D
WHERE A.DEPARTMENT_ID=B.DEPARTMENT_ID
AND B.LOCATION_ID=C.LOCATION_ID
AND C.COUNTRY_ID=D.COUNTRY_ID
AND C.COUNTRY_ID!='US'
ORDER BY 3;
(ANSI 조인)
SELECT A.EMPLOYEE_ID AS 사원번호,
A.EMP_NAME AS 사원명,
B.DEPARTMENT_ID AS 부서코드,
B.DEPARTMENT_NAME AS 부서명,
C.STREET_ADDRESS||' '||C.CITY||' '||C.STATE_PROVINCE||', '||
D.COUNTRY_NAME AS 부서주소,
D.COUNTRY_ID AS 국가코드
FROM HR.EMPLOYEES A
INNER JOIN HR.DEPARTMENTS B ON(A.DEPARTMENT_ID=B.DEPARTMENT_ID)
INNER JOIN HR.LOCATIONS C ON(B.LOCATION_ID=C.LOCATION_ID AND
C.COUNTRY_ID!='US')
INNER JOIN HR.COUNTRIES D ON(C.COUNTRY_ID=D.COUNTRY_ID)
ORDER BY 3;
3) SEMI JOIN
- 서브쿼리를 사용하여 추출된 중간결과만 메인쿼리에서 추출하는 조인
- IN과 EXISTS 연산자 사용
사용예) 사원테이블에서 급여가 10000이상되는 사원이 있는 부서정보를 조회하시오. Alias는 부서코드, 부서명
(EXISTS 연산)
SELECT A.DEPARTMENT_ID AS 부서코드,
A.DEPARTMENT_NAME AS 부서명
FROM HR.DEPARTMENTS A
WHERE EXISTS (SELECT 1 -- 서브쿼리, 서브쿼리 먼저 실행, 1은 의미 없음
FROM HR.EMPLOYEES B
WHERE A.DEPARTMENT_ID=B.DEPARTMENT_ID
AND B.SALARY>=10000)
ORDER BY 1;
(IN 연산자,비동등 조인)
SELECT A.DEPARTMENT_ID AS 부서코드,
A.DEPARTMENT_NAME AS 부서명
FROM HR.DEPARTMENTS A
WHERE A.DEPARTMENT_ID IN(SELECT DISTINCT DEPARTMENT_ID
FROM HR.EMPLOYEES
WHERE SALARY>=10000)
ORDER BY 1;
(동등 조인)
SELECT A.DEPARTMENT_ID AS 부서코드,
A.DEPARTMENT_NAME AS 부서명
FROM HR.DEPARTMENTS A,(SELECT DISTINCT DEPARTMENT_ID
FROM HR.EMPLOYEES
WHERE SALARY>=10000)B
WHERE A.DEPARTMENT_ID=B.DEPARTMENT_ID
ORDER BY 1;
5) NON EQUI JOIN
- 조인조건에 '=' 이외의 연산자가 사용되는 조인
사용예) 사원테이블에서 각 사원이 소속된 부서의 평균급여보다 더 많은 급여를 받는 사원의 사원번호,사원명,부서코드,입사일,급여를 조회하시오.
SELECT A.EMPLOYEE_ID AS 사원번호,
A.EMP_NAME AS 사원명,
A.DEPARTMENT_ID AS 부서코드,
(SELECT ROUND(AVG(SALARY))
FROM HR.EMPLOYEES D
WHERE D.DEPARTMENT_ID=A.DEPARTMENT_ID) AS 부서평균급여,
A.HIRE_DATE AS 입사일,
A.SALARY AS 급여
FROM HR.EMPLOYEES A
-- 부등호로 비교 >> 비동등 조인
WHERE A.SALARY > (SELECT C.ASAL
FROM (SELECT B.DEPARTMENT_ID,
AVG(B.SALARY) AS ASAL
FROM HR.EMPLOYEES B
GROUP BY B.DEPARTMENT_ID)C
WHERE A.DEPARTMENT_ID=C.DEPARTMENT_ID)
ORDER BY 3, 6 DESC;
사용예) 회원테이블에서 마일리지가 많은 상위 3명이 2020년 5월 구매한 정보를 조회하시오. Alias는 회원번호,회원명,구매금액 합계
(마일리지가 많은 3명)
SELECT A.MEM_ID
FROM (SELECT MEM_ID,MEM_MILEAGE
FROM MEMBER
ORDER BY MEM_MILEAGE DESC)A
WHERE ROWNUM<=3;
(2020년 5월 구매한 정보)
SELECT M.MEM_ID AS 회원번호,
M.MEM_NAME AS 회원명,
SUM(C.CART_QTY*PROD_PRICE) AS "구매금액 합계"
FROM CART C, MEMBER M, PROD P
WHERE C.CART_NO LIKE '202005%'
AND C.CART_PROD=P.PROD_ID
AND M.MEM_ID=C.CART_MEMBER
AND C.CART_MEMBER = ANY(SELECT A.MEM_ID
FROM (SELECT MEM_ID,MEM_MILEAGE
FROM MEMBER
ORDER BY MEM_MILEAGE DESC)A
WHERE ROWNUM<=3)
GROUP BY M.MEM_ID,M.MEM_NAME;
2. 외부조인(OUTER JOIN)
- 내부조인은 조인조건을 만족하는 자료를 대상으로 연산하고 조인조건을 만족하지 않는 자료는 모두 무시함.
- 외부조인은 자료의 종류가 많은 쪽을 기준으로 부족한 쪽의 테이블에 NULL값의 행을 추가하여 조인 수행
(사용형식:일반 외부조인)
SELECT 컬럼list
FROM 테이블1 [별칭1], 테이블2 [별칭2] [, 테이블3 [별칭3],...]
WHERE 별칭1.컬럼명=별칭2.컬럼명(+) -- 테이블2가 부족한 경우
- 조인대상 테이블 중 데이터가 부족한 테이블조인조건에 외부조인 연산자 '(+)'를 붙인다.
- 외부조인 조건이 여러 개인 경우 모두 '(+)'를 붙여야 함.
- 양쪽 모두 부족한 경우 허용되지 않음
- 한번에 한 테이블에만 외부조인 할 수 있다.
- ex) A,B,C 테이블이 외부조인하는 경우 A=B(+) AND C=B(+)는 허용되지 않음
- (+)연산자는 OR 연산자, IN 연산자와 같이 사용할 수 없음
- 외부조인조건과 일반조건을 같이 기술하면 외부조인 결과를 얻을 수 없다.
해결책으로 ANSI 외부조인으로 수행, 또는 서브쿼리를 사용한 외부조인으로 구성
(사용형식:ANSI 외부조인)
SELECT 컬럼list
FROM 테이블1 [별칭1]
LEFT|RIGHT|FULL OUTER JOIN 테이블2 [별칭2] ON(조인조건 [AND 일반조건])
:
[WHERE 일반조건]
- 'LEFT|RIGHT|FULL' : FROM절 쪽의 테이블의 자료가 더 많은 경우 LEFT
FROM절 쪽의 테이블의 자료가 더 적은 경우 RIGHT
양쪽 모두 부족한 경우 FULL
- 'WHERE 일반조건' : 모든 테이블에 공통으로 적용될 조건 기술(내부조인 결과로 변형될 위험이 상존)
- 그 외 특징은 INNER JOIN과 동일
사용예) HR계정의 테이블을 이용하여 모든 부서별 사원수와 평균급여를 조회하시오.
(잘못 사용된 예)
SELECT B.DEPARTMENT_ID AS 부서코드,
A.DEPARTMENT_NAME AS 부서명,
COUNT(*) AS 사원수,
NVL(ROUND(AVG(B.SALARY)),0) AS 평균급여
FROM HR.DEPARTMENTS A, HR.EMPLOYEES B -- 27개 11개
WHERE B.DEPARTMENT_ID(+)=A.DEPARTMENT_ID -- 외부조인조건
GROUP BY B.DEPARTMENT_ID, A.DEPARTMENT_NAME
ORDER BY 1;
(일반 외부조인)
SELECT A.DEPARTMENT_ID AS 부서코드,
A.DEPARTMENT_NAME AS 부서명,
COUNT(B.EMPLOYEE_ID) AS 사원수,
NVL(ROUND(AVG(B.SALARY)),0) AS 평균급여
FROM HR.DEPARTMENTS A, HR.EMPLOYEES B
WHERE A.DEPARTMENT_ID=B.DEPARTMENT_ID(+)
GROUP BY A.DEPARTMENT_ID, A.DEPARTMENT_NAME
ORDER BY 1;
(ANSI 외부조인)
SELECT A.DEPARTMENT_ID AS 부서코드,
A.DEPARTMENT_NAME AS 부서명,
COUNT(B.EMPLOYEE_ID) AS 사원수,
NVL(ROUND(AVG(B.SALARY)),0) AS 평균급여
FROM HR.DEPARTMENTS A
FULL OUTER JOIN HR.EMPLOYEES B ON(A.DEPARTMENT_ID=B.DEPARTMENT_ID) -- 외부조인조건
GROUP BY A.DEPARTMENT_ID, A.DEPARTMENT_NAME
ORDER BY 1;
사용예) 상품테이블과 분류테이블을 사용하여 모든 분류별 상품의 수를 조회하시오.
SELECT COUNT(*) FROM LPROD; -- 9개
SELECT COUNT*DISTINCT PROD_LGU) FROM PROD; -- 6개
(일반 외부조인)
SELECT A.LPROD_GU AS 분류코드,
A.LPROD_NM AS 분류명,
COUNT(B.PROD_ID) AS "상품의 수"
FROM LPROD A, PROD B
WHERE A.LPROD_GU=B.PROD_LGU(+)
GROUP BY A.LPROD_GU, A.LPROD_NM
ORDER BY 1;
(ANSI 외부조인)
SELECT A.LPROD_GU AS 분류코드,
A.LPROD_NM AS 분류명,
COUNT(B.PROD_ID) AS "상품의 수"
FROM PROD B
RIGHT OUTER JOIN LPROD A ON(A.LPROD_GU=B.PROD_LGU)
GROUP BY A.LPROD_GU, A.LPROD_NM
ORDER BY 1;
사용예) 2020년 4월 모든 상품별 매입집계(수량집계,금액집계)를 조회하시오.
(일반 외부조인)
SELECT B.PROD_ID AS 상품코드,
B.PROD_NAME AS 상품명,
COUNT(A.BUY_QTY) AS 매입건수,
NVL(SUM(A.BUY_QTY),0) AS 매입수량합계,
NVL(SUM(A.BUY_QTY*B.PROD_COST),0) AS 매입금액합계
FROM BUYPROD A, PROD B
WHERE A.BUY_PROD(+)=B.PROD_ID
AND A.BUY_DATE BETWEEN TO_DATE('20200401') AND TO_DATE('20200430')
GROUP BY B.PROD_ID, B.PROD_NAME
ORDER BY 1;
(ANSI 외부조인)
SELECT B.PROD_ID AS 상품코드,
B.PROD_NAME AS 상품명,
COUNT(A.BUY_QTY) AS 매입건수,
NVL(SUM(A.BUY_QTY),0) AS 매입수량합계,
NVL(SUM(A.BUY_QTY*B.PROD_COST),0) AS 매입금액합계
FROM BUYPROD A
RIGHT OUTER JOIN PROD B ON(A.BUY_PROD=B.PROD_ID AND
A.BUY_DATE BETWEEN TO_DATE('20200401') AND TO_DATE('20200430'))
GROUP BY B.PROD_ID, B.PROD_NAME
ORDER BY 1;
(서브쿼리를 이용한 외부조인)
(서브쿼리:2020년 4월 매입집계 : 내부조인)
SELECT A.BUY_PROD AS BID,
SUM(A.BUY_QTY) AS SCNT,
SUM(A.BUY_QTY*B.PROD_COST) AS SAMT
FROM BUYPROD A, PROD B
WHERE A.BUY_DATE BETWEEN TO_DATE('20200401') AND TO_DATE('20200430')
AND A.BUY_PROD=B.PROD_ID
GROUP BY A.BUY_PROD;
(메인쿼리:모든 상품에 대하여 상품코드,상품명,매입수량합계,매입금액합계)
SELECT P.PROD_ID AS 상품코드,
P.PROD_NAME AS 상품명,
NVL(C.SCNT,0) AS 매입수량합계,
NVL(C.SAMT,0) AS 매입금액합계
FROM PROD P, (SELECT A.BUY_PROD AS BID,
SUM(A.BUY_QTY) AS SCNT,
SUM(A.BUY_QTY*B.PROD_COST) AS SAMT
FROM BUYPROD A, PROD B
WHERE A.BUY_DATE BETWEEN TO_DATE('20200401') AND TO_DATE('20200430')
AND A.BUY_PROD=B.PROD_ID
GROUP BY A.BUY_PROD)C
WHERE P.PROD_ID=C.BID(+)
ORDER BY 1;
사용예) 2020년 4월 모든 상품별 매출집계(수량집계,금액집계)를 조회하시오.
(일반 외부조인)
SELECT B.PROD_ID AS 상품코드,
B.PROD_NAME AS 상품명,
NVL(SUM(A.CART_QTY),0) AS 매출수량합계,
NVL(SUM(A.CART_QTY*B.PROD_PRICE),0) AS 매출금액합계
FROM CART A, PROD B
WHERE A.CART_PROD(+)=B.PROD_ID
AND A.CART_NO LIKE '202004%'
GROUP BY B.PROD_ID, B.PROD_NAME
ORDER BY 1;
(ANSI 외부조인)
SELECT B.PROD_ID AS 상품코드,
B.PROD_NAME AS 상품명,
NVL(SUM(A.CART_QTY),0) AS 매출수량합계,
NVL(SUM(A.CART_QTY*B.PROD_PRICE),0) AS 매출금액합계
FROM CART A
RIGHT OUTER JOIN PROD B ON(A.CART_PROD=B.PROD_ID AND
A.CART_NO LIKE '202004%')
GROUP BY B.PROD_ID, B.PROD_NAME
ORDER BY 1;
(서브쿼리)
SELECT B.PROD_ID AS BID,
SUM(A.CART_QTY) AS SCNT,
SUM(A.CART_QTY*B.PROD_PRICE) AS SAMT
FROM CART A, PROD B
WHERE A.CART_PROD=B.PROD_ID
AND A.CART_NO LIKE '202004%'
GROUP BY B.PROD_ID,B.PROD_NAME;
(메인쿼리)
SELECT P.PROD_ID AS 상품코드,
P.PROD_NAME AS 상품명,
NVL(C.SCNT,0) AS 매출수량합계,
NVL(C.SAMT,0) AS 매출금액합계
FROM PROD P, (SELECT B.PROD_ID AS BID,
SUM(A.CART_QTY) AS SCNT,
SUM(A.CART_QTY*B.PROD_PRICE) AS SAMT
FROM CART A, PROD B
WHERE A.CART_PROD=B.PROD_ID
AND A.CART_NO LIKE '202004%'
GROUP BY B.PROD_ID,B.PROD_NAME) C
WHERE P.PROD_ID=C.BID(+)
ORDER BY 1;
문제] 2020년 6월 모든 상품별 매입/매출 집계를 조회하시오.
(ANSI 외부조인)
SELECT A.PROD_ID AS 상품코드,
A.PROD_NAME AS 상품명,
NVL(SUM(B.BUY_QTY),0) AS 매입수량합계,
NVL(SUM(C.CART_QTY),0) AS 매출수량합계,
NVL(SUM(B.BUY_QTY*A.PROD_COST),0) AS 매입금액합계,
NVL(SUM(C.CART_QTY*A.PROD_PRICE),0) AS 매출금액합계
FROM PROD A
LEFT OUTER JOIN BUYPROD B ON(A.PROD_ID=B.BUY_PROD AND B.BUY_DATE BETWEEN TO_DATE('20200601') AND TO_DATE('20200630'))
LEFT OUTER JOIN CART C ON(A.PROD_ID=C.CART_PROD AND C.CART_NO LIKE '202006%')
GROUP BY A.PROD_ID, A.PROD_NAME
ORDER BY 1;
(메인쿼리)
SELECT P.PROD_ID AS 상품코드,
P.PROD_NAME AS 상품명,
NVL(D.SCNT,0) AS 매입수량합계,
NVL(C.SCNT,0) AS 매출수량합계,
NVL(D.SAMT,0) AS 매입금액합계,
NVL(C.SAMT,0) AS 매출금액합계
FROM PROD P,
(SELECT B.PROD_ID AS BID, -- 매출
SUM(A.CART_QTY) AS SCNT,
SUM(A.CART_QTY*B.PROD_PRICE) AS SAMT
FROM CART A, PROD B
WHERE A.CART_PROD=B.PROD_ID
AND A.CART_NO LIKE '202006%'
GROUP BY B.PROD_ID,B.PROD_NAME) C,
(SELECT A.BUY_PROD AS BID, -- 매입
SUM(A.BUY_QTY) AS SCNT,
SUM(A.BUY_QTY*B.PROD_COST) AS SAMT
FROM BUYPROD A, PROD B
WHERE A.BUY_DATE BETWEEN TO_DATE('20200601') AND TO_DATE('20200630')
AND A.BUY_PROD=B.PROD_ID
GROUP BY A.BUY_PROD) D
WHERE P.PROD_ID=C.BID(+)
AND P.PROD_ID=D.BID(+)
ORDER BY 1;
'DBMS' 카테고리의 다른 글
[DBMS/Oracle] 집합 연산자 (0) | 2023.03.16 |
---|---|
[DBMS/Oracle] 서브쿼리(SUBQUERY) (1) | 2023.03.16 |
[DBMS/Oracle] ROLLUP과 CUBE함수 (0) | 2023.03.15 |
[DBMS/Oracle] 그룹함수 (0) | 2023.03.15 |
[DBMS/Oracle] 함수 (0) | 2023.03.15 |