insert into ot_test1 values('1','a','A',''); insert into ot_test1 values('1','a','B','!'); insert into ot_test1 values('1','b','A','@'); insert into ot_test1 values('2','a','A','#'); insert into ot_test1 values('3','a','A','');
insert into ot_test2 values('1','a','A','G'); insert into ot_test2 values('1','a','A','X'); insert into ot_test2 values('1','b','A','F');
select a.col1 a1, a.col2 a2, a.col3 a3, b.col4 from ot_test1 a, ot_test2 b where 1=1 and a.col1 = b.col1(+) and a.col2 = b.col2(+) and a.col3 = b.col3(+) ;
집합 A 에 5 개 rows 를 넣었고 집합 B 에는 3 개의 rows 를 넣었다.
아우터의 기준이 되는 A 의 5 개는 모두 나온다.
col1=1 col2=a col3=A 인 조인조건을 만족하는 B 집합이 2개가 모두 리턴된다.
## 아우터 조인은 1:1 관계 에서는 스칼라 서브쿼리로 변경 가능하다.
select a.col1 a1, a.col2 a2, a.col3 a3, (select b.col4 from ot_test2 b where 1=1 and a.col1 = b.col1 and a.col2 = b.col2 and a.col3 = b.col3 ) b4 from ot_test1 a order by a1, a2, a3 ; => ORA-001427
1:1 관계가 아닌 아우터 조인을 스칼라 서브쿼리로 변경하면 ORA-001427 가 뜬다.
이때 min, max 등의 그룹함수를 사용하면 에러를 회피할 수 있다.
select a.col1 a1, a.col2 a2, a.col3 a3, (select min(b.col4) from ot_test2 b where 1=1 and a.col1 = b.col1 and a.col2 = b.col2 and a.col3 = b.col3 ) b4 from ot_test1 a order by a1, a2, a3 ; => 스칼라서브쿼리에서 2개 이상의 행이 리턴되는 것을 막기 위해 min 함수를 썼다.
3. 연속 아우터 조인
중첩해서 아우터 조인을 사용할 경우도 있다.
이럴때는 어디에 (+) 를 표시해야 할까.
-- consecutive out join
drop table out_a; drop table out_b; drop table out_c;
create table out_a( col1 int, col2 varchar2(1) );
create table out_b( col1 int, col2 varchar2(1) );
create table out_c( col1 int, col2 varchar2(1) );
insert into out_a values(1,'a'); insert into out_a values(2,'b'); insert into out_a values(3,'G'); insert into out_a values(4,'');
insert into out_b values(1,'a'); insert into out_b values(3,''); insert into out_b values(5,''); insert into out_b values(6,'d');
insert into out_c values(1,'a'); insert into out_c values(2,'a'); insert into out_c values(3,'c'); insert into out_c values(3,'f'); insert into out_c values(6,'a');
-- 올바른 중첩 아우터 조인 쿼리
SELECT * FROM OUT_A A ,OUT_B B ,OUT_C C WHERE A.COL1 = B.COL1(+) AND B.COL1 = C.COL1(+) ORDER BY A.COL1 ;
-- 잘못 작성된 아우터 조인
SELECT * FROM OUT_A A ,OUT_B B ,OUT_C C WHERE A.COL1 = B.COL1(+) AND B.COL1 = C.COL1 ORDER BY A.COL1 ;
이것의 결과는 일반조인의 결과와 같다.
-- 일반적인 조인
SELECT * FROM OUT_A A ,OUT_B B ,OUT_C C WHERE A.COL1 = B.COL1 AND B.COL1 = C.COL1 ORDER BY A.COL1 ;
## A = B(+) and B(+) = C 이런 아우터 조인은 가능할까?
-- 이런 아우터 조인이 될까
SELECT * FROM OUT_A A ,OUT_B B ,OUT_C C WHERE A.COL1 = B.COL1(+) AND B.COL1 (+) = C.COL1 ORDER BY A.COL1 => 이 결과는 A 와 B 의 아우터 조인 집합과 C의 카티션 곱이다.
4. Full outer join
오라클은 아우터 조인되는 집합쪽에 (+) 기호를 넣는다.
그렇다면 양쪽 아우터 조인은 양쪽 집합에 (+) 를 넣으면 될것 같은데 그렇게 하면 에러가 난다.
full outer join 은 ansi 방식으로 작성하거나 왼쪽 아우터 조인 오른쪽 아우터 조인을 union 하는 방식으로 쓸수 있다.
-- FULL OUTER JOIN
drop table out_a; drop table out_b;
create table out_a( col1 int, col2 varchar2(1) );
create table out_b( col1 int, col2 varchar2(1) );
insert into out_a values(1,'a'); insert into out_a values(3,'c'); insert into out_a values(5,'');
insert into out_b values(1,'a'); insert into out_b values(4,'%'); insert into out_b values(5,'$');
-- 일반조인
SELECT A.COL1, B.COL1, A.COL2, B.COL2 FROM out_a A, out_b B WHERE A.COL1 = B.COL1 ;
-- 맞지않는 문법
SELECT A.COL1, B.COL1, A.COL2, B.COL2 FROM out_a A, out_b B WHERE A.COL1(+) = B.COL1(+) ; => ORA-01468
-- ansi
SELECT A.COL1, B.COL1, A.COL2, B.COL2 FROM out_a A full outer join out_b B ON A.COL1 = B.COL1 ORDER BY a.COL1 ;
-- union
SELECT A.COL1, B.COL1, A.COL2, B.COL2 FROM out_a A, out_b B WHERE A.COL1 = B.COL1(+) UNION SELECT A.COL1, B.COL1, A.COL2, B.COL2 FROM out_a A, out_b B WHERE A.COL1(+) = B.COL1 ;
5. Lateral outer join
Lateral 구문은 오라클에서 좀 더 유연하게 아우터 조인을 사용하는 것을 지원한다.
오라클 아우터 조인은 조인 조건에 in 이나 or 가 올 경우 에러가 난다.
SELECT A.EMPNO, B.DNAME FROM EMP A, DEPT B WHERE A.DEPTNO = B.DEPTNO(+) OR A.DEPTNO = B.DEPTNO2(+)
=> 에러
위의 SQL 은 아래와 같이 or 조건을 union 으로 분리해서 작성해야 정상 동작한다.
SELECT A.EMPNO, B.DNAME FROM EMP A, DEPT B WHERE A.DEPTNO = B.DEPTNO(+) UNION SELECT A.EMPNO, B.DNAME FROM EMP A, DEPT B WHERE A.DEPTNO = B.DEPTNO2(+)
해당 SQL은 lateral 을 사용하면 좀 더 간결하게 작성할수 있다.
SELECT A.EMPNO, B.DNAME FROM EMP A , LATERAL ( SELECT B.DNAME FROM DEPT B WHERE A.DEPTNO = B.DEPTNO OR A.DEPTNO = B.DEPTNO2 ) (+)B
1. 달러환율 안정세 접어들고 # 달러스왑 미국에서 적극적이었던 이유는 미국채권금리 상승하는 것을 막기위함 같다. 외환당국은 달러를 보유해야하는데 일부는 실물달러가 아닌 달러자산으로 보유한다. 미국채권이 그중하나이고 한국에서 달러가 부족해지면 미국채권을 팔게되니 이를 막기위함이아닐까. 절대 한국이 이뻐서가 아니다 2. 셧다운 지속되는 외국보다 한국 투자 환경이 좋다. 3. 벨류에이션 매력. 많은 기업들의 주가가 자사주 매입 가격 이하였다. 자신의 가치를 아는 내부자들은 이미 자사주 매입 움직임이 있었다. 반면 , 위닉스는 자사주 처분 공시. 실적이 지속적 하락세, 중국공장 가동률 떨어지면서 하늘이 맑은날이 지속됨. 기업입장에서는 합리적선택이지만 주주입장에 반하는 행동.