9월 14일 내 강의 정리 아직 정리안함

 SELECT *

FROM customer;


cid : customer id 

cnm : customer name 


SELECT * 

FROM product; 




product 제품

pid : PRODUCT ID 제품 번호

PNM  : PRODUCT NAME 제품 이름 


cycle : 고객 애음주기 


SELECT * 

FROM cycle; 


cid : customer id 

pid product id 

day : 애음요일 


1-7 까지 일요일부터 토요일까지 


cnt : count, 수량 



고객애음주기가 일실적 테이블에 갔을때는 


요일인 day 가 일자 dt 로 간다. 



실제고객이 월요일날 먹는다고 할때 휴가가면 다음주에받을테니까

그걸 실제로 반영하려고 


*모델링 png 를 보기 ( 사진 ) 



실습 4번 



SELECT * 

FROM cycle 


SELECT *

FROM customer


SELECT cycle.cid, customer.cnm, cycle.pid, cycle.day, cycle.cnt 

FROM customer JOIN cycle  ON customer.cid = cycle.cid 

WHERE cnm IN ('brown' ,'sally' ) 


SELECT cid, cnm, pid, day, cnt 

FROM customer JOIN cycle 





1. natural join , join with using , join with on , oracle  

1. natural join 

SELECT cid, cnm, pid, day, cnt 

FROM customer NATURAL JOIN cycle 

WHERE cnm = 'brown' OR cnm = 'sally'


--중요한 것 : natural join 에서는 한정자 dept를 from 절에 안쓰고, 그냥 테이블명만

--두개 쓰면 됨 


2. JOIN WITH USING  



관계선 클릭 하면 : 두테이블 컬럼 빨강, 파랑 두개 컬럼으로 연결이 되어 있다. 



부모자식간의 관계 


customer와 cycle사이에는 customer 가 부모관계 cycle은 자식 

조인을 하면 자식쪽으로 맞춰줌 


SELECT customer.* , pid, day, cycle.cnt  

FROM customer , cycle

WHERE customer.cid = cycle.cid 

 AND customer.cnm IN ( 'brown', 'sally' ); 

cid_1 하나가 생겼다. 


ansi sql 



5번 



customer , cycle, product 



SELECT * 

FROM customer


SELECT * 

FROM cycle


SELECT * 

FROM product 





SELECT 

FROM 

WHERE cnn IN ( brown, sally ) ; 



SELECT cycle.cid, customer.cnm, cycle.pid, cycle.day, cycle.cnt 

FROM customer,cycle  

WHERE cnm IN ('brown' ,'sally' ) 

AND customer.cid = cycle.cid 

AND product.pid = cycle.pid 


SQL 실행에 대한 순서가 없다. 


조인할 테이블에 대해서 FROM 절에 기술한 순으로

테이블을 읽지 않음. 


FROM customer, cycle, product 라고 써놔도 오라클이 읽는 순서는 변경될 수 있다. 


SELECT *

FROM customer, cycle, product 

WHERE customer.cid = cycle.cid 

AND customer.cnm IN ( 'brown', 'sally' ) 




-사진 찍어놓음 . 


EXPRAIN PLAN FOR 를 쓰면 어떻게 설명되었는지 나온다. 

테이블위에 쓰고 컨트롤 엔터 



SELECT * 

FROM TABLE (DBMS_XPLAN.DISPLAY) ; 이걸 하면


어떻게 실행됬는지 나온다. 



6번이랑  13번까지 - > 수요일까지 ㅅ훅제 



JOIN 구분 



1. 문법에 따른 구분 : ANSI 냐, ORACLE 이냐

2. JOIN 의 형태로 구분 : SELF JOIN , NONEQUI-JOIN , CROSS-JOIN

3. 조인 성공여부에 따라 데이터 표시여부 

: INNER JOIN - 조인이 성공했을때 데이터를 표시 

: OUTER JOIN - 조인이 실패해도 기준으로 정한 테이블의 컬럼 정보는 표시 

( 예시 : MGR 과 EMPNO 로 셀프조인했을때 KING  도 나옴 ) 


-- PPT 참고 




사번, 사원의 이름, 관리자 사번, 관리자 이름 


SELECT a.empno, a.ename ,  b.empno managernumber , b.ename managerna

FROM emp a , emp b

WHERE a.mgr = b.empno

( king ( president) 의 경우 ,mgr 컬럼의 값이 null이기 때문에 조인에 실패. 

--> 13건이 나온다. 


ansi 로 


SELECT a.empno, a.ename ,  b.empno managernumber , b.ename managerna

FROM emp a join  emp b on ( a.mgr = b.empno ) 



SELECT * 

FROM emp





outer join 



SELECT a.empno, a.ename ,  b.empno managernumber , b.ename managerna

FROM emp a left join  emp b on ( a.mgr = b.empno ) 


-> 조인에 실패하더라도 왼쪽에 있는 세개값이 나오는데 manager는 null값이었고

manager네임은 없었으니까 가까올수없으니까 null로 나온다. 


lfft outer 냐 right outer 냐 방향성이다. 


SELECT a.empno, a.ename ,  b.empno managernumber , b.ename managerna

FROM emp b right join  emp a on ( a.mgr = b.empno )

FROM 절에서 두개만 바꿔주면 결과는 동일하게 나온다. 



OUTER 



행에 대한 제한 조건을 기술시 WHERE 절에 기술 했을 때와 ON 절에 기술 했을 때 

결과가 다르다. 



사원의 부서가 10번인 사람들만 조회 되도록 부서 번호 조건을 추가 

SELECT a.empno, a.ename ,  b.empno managernumber , b.ename managerna

FROM emp a left join  emp b on ( a.mgr = b.empno ) 


OUTER 조인에서는 ON 절에다 WHERE 에다가 결과가 달라짐 


SELECT a.empno, a.ename ,  b.empno managernumber , b.ename managerna

FROM emp a left join  emp b on ( a.mgr = b.empno ) 






SELECT e.empno, e.ename ,  e.deptno , e.mgr,  m.ename , m.deptno

FROM emp e LEFT OUTER JOIN  emp m on ( e.mgr = m.empno ) 

WHERE e.deptno = 10; 


OUTER 조인 을 한 뒤에 DEPTNO 가 10인 애로 제한 


--> outer join 이 아닌 inner 조인 결과가 나온다 





SELECT e.empno, e.ename ,  e.deptno , e.mgr,  m.ename , m.deptno

FROM emp e JOIN  emp m on ( e.mgr = m.empno ) 

WHERE e.deptno = 10; 


조건을 어디에다가 기술하느냐에 따라서 쓰임이 달라진다. 





SELECT  * 

from emp










oracle sql 



오라클 sql과 안시랑 표현이 안되는부분이 있다. 













outer join : 데이터가 없는 쪽의 컬럼에 + 기호를 붙인다. 


데이터가 없는 쪽 : ansi sql 에서는 기준 테이블 반대편쪽 테이블의 컬럼에 + 을 붙인다. 

                WHERE 절 연결 조건에 적응


SELECT a.empno, a.ename ,  b.empno managernumber , b.ename managerna

FROM emp a left join  emp b on ( a.mgr = b.empno ) 



SELECT a.empno, a.ename ,  b.empno managernumber , b.ename managerna

FROM emp b right join  emp a on ( a.mgr = b.empno )

FROM 절에서 두개만 바꿔주면 결과는 동일하게 나온다. 



플러스를 어디에 붙여야 하는지에대해서 


SELECT e.empno, e.ename, e.mgr, m.ename

FROM emp e, emp m 

WHERE e.mgr = m.empno ( + ) ; 



연결에 실패하는 쪽 다 플러스 붙여야하고 플러스빼면 이너조인이다 




SELECT e.empno, e.ename, e.mgr, m.empno, m.ename 

FROM emp e RIGHT OUTER JOIN emp ON(e.mgr = m.empno) ; 


21건과 13건 이렇게 차이가 나는 이유는 


오라클에서는 full outer 가 적용되지 않다. 


검증하기 . 



union  두개를 합치는 것 . 위쪽에랑 아랫쪽에 있는 결과를 행으로 합친다. 



SELECT e.ename, m.ename 

FROM emp e LEFT OUTER JOIN emp m ON ( e.mgr = m.empno) 

UNION

SELECT e.ename, m.ename 

FROM emp e RIGHT OUTER JOIN emp m ON ( e.mgr = m.empno) 

MINUS 

SELECT e.ename, m.ename 

FROM emp e  FULL JOIN emp m ON ( e.mgr = m.empno) ; 



----> 합집합 full outer 가 된다.  

중복이 제거가 된다. 



SELECT e.ename, m.ename 

FROM emp e full FULL JOIN emp m ON ( e.mgr = m.empno) ; 





SELECT e.ename, m.ename 

FROM emp e LEFT OUTER JOIN emp m ON ( e.mgr = m.empno) 

UNION

SELECT e.ename, m.ename 

FROM emp e RIGHT OUTER JOIN emp m ON ( e.mgr = m.empno) 

INTERSECT

SELECT e.ename, m.ename 

FROM emp e  FULL JOIN emp m ON ( e.mgr = m.empno) ; 


22건이 나옴 위에 집합이랑 아래집합이랑 결과적으로 동일하다라는 결과를 가지고 있을 때 





실습 


OUTERJOIN1 


SELECT * 

FROM buyprod 



SELECT * 

FROM buyprod 

WHERE BUY_DATE = TO_DATE('2005/01/25', 'YYYY/MM/DD'); 



SELECT *

FROM prod ; 


SELECT b.buy_date , b.buy_prod , p.prod_id, p.prod_name , b.buy_qty 

FROM buyprod b , prod p 

WHERE  b.buy_prod(+) = p.prod_id 

AND b.buy_date(+)   =  TO_DATE('2005.01.25' , 'YYYY.MM.DD') ; 


아우터조인이랑 컬럼연결이 실패해도 기준이 되는 테이블의 데이터가 나오도록하는것

즉 기준이 되어야 하는 테이블은 prod 테이블이어야 한다. 



SELECT b.buy_date , b.buy_prod , p.prod_id, p.prod_name , b.buy_qty 

FROM buyprod b RIGHT OUTER JOIN prod p 

ON ( b.buy_prod = p.prod_id  

AND b.buy_date   =  TO_DATE('2005.01.25' , 'YYYY.MM.DD') ) ; 


* 기준을 잘 삼아야 한다. 안시에서는 어떻게 설명했고 오라클에서는 어떻게 설명했는지. 

댓글