[Oracle SQL]外部結合
外部結合
1つ以上の条件が
また、cテーブルを基準にBテーブルを拡張することはできません.
WHERE A=B(+)
AND C=D(+)
(通常の外部結合形式を使用)
SELECT列リスト
FROM表名1[別名1]、表名2[別名2],[,表名3[別名3],...]
WHERE別名1.カラム名1(+)=別名2.カラム名2--=(+)も使用できます.
:
(ANSI外部結合形式を使用)
SELECT列リスト
FROMテーブル名1[別名1]
FULL|RIGHT|LEFTOUTER JOIN表名2[別名2]ON(接続条件[AND一般条件])
:
[WHERE一般条件];
-- FULL|RIGHT|LEFT
-FULL:両方とも足りない
-RIGHT:OUTER JOIN節の「表名2」はFROM節の「表名1」よりも多い
-LEFT:OUTER JOIN節の「表名2」のデータはFROM節の「表名1」より多い
**一般外部結合を使用する場合、結合条件と一般条件を同時に適用した場合、正しい結果は返されません-(ソリューション=>サブクエリまたはANSI外部結合を使用)
使用例)すべての分類商品の数量を問い合わせる--「すべて」外部結合
SELECT COUNT(DISTINCT PROD_LGU) FROM PROD;
--상품테이블에서 분류코드는 6개 LPROD 분류코드는 9개
--분류코드는 A,B 두테이블둘다 있음. SELECT절에서 쓸때 무조건 많은 쪽 테이블걸 써야함.
SELECT A.LPROD_GU AS 분류코드,
A.LPROD_NM AS 분류명,
COUNT(B.PROD_ID) AS "상품의 수 "
-- 외부조인할 때 COUNT쓸때 *쓰면안됨. NULL값을 같는 행도 한줄로 취급되어짐.
-- 때문에 Null값이 없는 기본키 PROD 컬럼명하나 써줌
FROM LPROD A, PROD B
WHERE A.LPROD_GU=B.PROD_LGU(+)
GROUP BY A.LPROD_GU, A.LPROD_NM
ORDER BY 1;
(ANSI FORMAT) SELECT A.LPROD_GU AS 분류코드,
A.LPROD_NM AS 분류명,
COUNT(B.PROD_ID) AS "상품의 수"
FROM LPROD A
LEFT OUTER JOIN PROD B ON(A.LPROD_GU=B.PROD_LGU)
GROUP BY A.LPROD_GU, A.LPROD_NM
ORDER BY 1;
使用例)2005年4月のすべての商品の購入統計を調べてください.Aliasは商品コード、商品名、購入数量(統計)と購入金額を提供します.
--26개밖에 안나옴
SELECT DISTINCT BUY_PROD
FROM BUYPROD
WHERE BUY_DATE BETWEEN TO_DATE('20050401')
AND TO_DATE('20050430') -- 4월에 매입된 상품 26개
SELECT B.PROD_ID AS 상품코드,
-- 상품코드는 A,B 테이블 둘다 있음 더많은 PROD 테이블의 상품코드를 써야함.
B.PROD_NAME AS 상품명,
SUM(A.BUY_QTY) AS 매입수량,
SUM(A.BUY_QTY*B.PROD_COST) AS 매입금액
-- PROD의 매입단가를 쓰는게 좋음
FROM BUYPROD A, PROD B
WHERE A.BUY_PROD(+)=B.PROD_ID --외부조인
AND A.BUY_PROD=B.PROD_ID AND A.BUY_DATE BETWEEN TO_DATE('20050401') AND TO_DATE('20050430')
GROUP BY B.PROD_ID, B.PROD_NAME
ORDER BY 1 ;
(ANSI)--結果74行 SELECT B.PROD_ID AS 상품코드,
- 상품코드는 A,B 테이블 둘다 있음 더많은 PROD 테이블의 상품코드를 써야함.
B.PROD_NAME AS 상품명,
NVL(SUM(A.BUY_QTY),0) AS 매입수량,
NVL(SUM(A.BUY_QTY*B.PROD_COST),0) AS 매입금액
-- PROD의 매입단가를 쓰는게 좋음
FROM BUYPROD A
RIGHT OUTER JOIN PROD B ON (A.BUY_PROD=B.PROD_ID AND A.BUY_DATE BETWEEN TO_DATE('20050401') AND TO_DATE('20050430'))
GROUP BY B.PROD_ID, B.PROD_NAME
ORDER BY 1 ;
(サブクエリ)--結果74行 SELECT B.PROD_ID AS 상품코드,
-- 상품코드는 A,B 테이블 둘다 있음 더많은 PROD 테이블의 상품코드를 써야함.
B.PROD_NAME AS 상품명,
NVL(D.CAMT,0) AS 매입수량,
NVL(D.SAMT,0) AS 매입금액
-- PROD의 매입단가를 쓰는게 좋음
FROM PROD B,
(--2005년 4월 상품별 매입집계=내부조인. 기간(일반조건)을 처리해줌
SELECT A.BUY_PROD AS BID,
SUM(A.BUY_QTY) AS CAMT,
SUM(A.BUY_QTY*C.PROD_COST) AS SAMT
FROM BUYPROD A, PROD C
WHERE A.BUY_DATE BETWEEN TO_DATE('20050401') AND TO_DATE('20050430')
AND A.BUY_PROD=C.PROD_ID
GROUP BY A.BUY_PROD)D
WHERE B.PROD_ID=D.BID(+)
ORDER BY 1;
使用例)2005年4月の全商品の販売統計を調べてください商品コード、商品名、販売数量(統計)、販売金額
--2005년 4월 모든 상품별 매출
-- AND A.BUY_PROD=B.PROD_ID AND A.BUY_DATE BETWEEN TO_DATE('20050401') AND TO_DATE('20050430')
GROUP BY B.PROD_ID, B.PROD_NAME
ORDER BY 1 ;
(一般結合) SELECT A.PROD_ID AS 상품코드,
A.PROD_NAME AS 상품명,
SUM(B.CART_QTY) AS 매출수량,
SUM(A.PROD_PRICE*B.CART_QTY) AS 매출금액
FROM PROD A, CART B
WHERE B.CART_PROD(+)=A.PROD_ID
AND A.PROD_ID=B.CART_PROD
AND B.CART_NO LIKE '200504%'
GROUP BY A.PROD_ID, A.PROD_NAME
ORDER BY 1;
(ANSI) SELECT A.PROD_ID AS 상품코드,
A.PROD_NAME AS 상품명,
NVL(SUM(B.CART_QTY),0) AS 매출수량,
NVL(SUM(A.PROD_PRICE*B.CART_QTY),0) AS 매출금액
FROM PROD A
LEFT OUTER JOIN CART B ON(A.PROD_ID=B.CART_PROD
AND B.CART_NO LIKE '200504%')
GROUP BY A.PROD_ID, A.PROD_NAME
ORDER BY 1;
(サブクエリ) SELECT A.PROD_ID AS 상품코드,
A.PROD_NAME AS 상품명,
NVL(D.BB,0) AS 매출수량,
NVL(D.CC,0) AS 매출금액
FROM PROD A, ( --2005년 4월 일반조건
SELECT B.PROD_ID AS AA ,
SUM(C.CART_QTY) AS BB ,
SUM(B.PROD_PRICE*C.CART_QTY) AS CC
FROM PROD B, CART C
WHERE C.CART_NO LIKE '200504%'
AND B.PROD_ID=C.CART_PROD
GROUP BY B.PROD_ID)D
WHERE A.PROD_ID=D.AA(+)
ORDER BY 1;
使用例)2005年4月の全商品の販売統計を調べてくださいAliasは商品コード、商品名、購入数量、販売数量、購入金額、販売金額を提供します
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('20050401') AND TO_DATE('20050430'))
LEFT OUTER JOIN CART C ON(C.CART_PROD=A.PROD_ID
AND C. CART_NO LIKE '200504%')
GROUP BY A.PROD_ID, A.PROD_NAME
ORDER BY 1;
使用例)hr勘定科目の表を使用して、「すべて」部門の従業員数と平均勤続年数、平均給与を問い合わせる--すべての->外部結合、部門->グループ・セクション、人数->COUNTカッコ内のプライマリ・キー
Aliasは部門コード、部門名、人員数、平均勤務年数、平均賃金です.
SELECT B.DEPARTMENT_ID AS 부서코드, --EMP, DEPT에 둘다 있음. EMP 쓰면 널값 16개 DEPT 쓰면 1개의 널값 양쪽이 다 부족
B.DEPARTMENT_NAME AS 부서명,
COUNT(A.EMPLOYEE_ID) AS 인원수,
NVL(ROUND(AVG(EXTRACT(YEAR FROM SYSDATE) -EXTRACT(YEAR FROM A.HIRE_DATE))),0) AS 평균근무년수,
NVL(ROUND(AVG(A.SALARY)),0) AS 평균급여
FROM HR.EMP A
FULL OUTER JOIN HR.DEPT B ON(A.DEPARTMENT_ID= B.DEPARTMENT_ID) -- 양쪽이 다 부족해서 FULL OUTER JOIN
GROUP BY B.DEPARTMENT_ID, B.DEPARTMENT_NAME
ORDER BY 1;
使用例)2005年6月のすべての会員の購入状況である「すべて」の外部署名を確認してください.Aliasは会員番号、会員名、購入数、購入金額です.
SELECT A.MEM_ID AS 회원번호,
A.MEM_NAME AS 회원명,
NVL(SUM(B.CART_QTY),0) AS 구매수량,
NVL(SUM(B.CART_QTY*C.PROD_PRICE),0) AS 구매금액
FROM MEMBER A --"회원별"-MEMBER테이블이 젤 많이 정보 가짐
LEFT OUTER JOIN CART B ON (A.MEM_ID = B.CART_MEMBER AND B.CART_NO LIKE '200506%')
LEFT OUTER JOIN PROD C ON (C.PROD_ID=B.CART_PROD) -- A,B조인결과와 조인
GROUP BY A.MEM_ID, A.MEM_NAME
ORDER BY 1;
Reference
この問題について([Oracle SQL]外部結合), 我々は、より多くの情報をここで見つけました https://velog.io/@vgo_dongv/Oracle-SQL-외부조인テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol