이런것도 가능할까요? 0 7 2,691

by 손님 [Oracle 기초] 조인 [2011.01.04 12:37:01]


여러 조인은 해 봤지만.. 뭔가 될것 같으면서 안되네요..^^;

a_table
arc_pk, gubun, youngsu_p
1 , 1 , 100
1 , 2 , 200
2 , 2 , 200

b_table
pk, type, category
1 , 2 , 101

c_table
pk, data_1, data_2
1 , 'yes' , '사과'
2 , 'no' , '배'

이렇게 있을때.. a_table 은 b_table 과 c_table 의 영수값을 모두 가지고 있습니다.
a_table 에서 b_table 과 c_table 의 구분은 gubun 값으로 1이면 b_table , 2면 c_table 일때

select a_table.gubun
    , case when a_table.gubun = 1 and b_table.type = 2 then a_table.youngsu_p end a_data
    , case when a_table.gubun = 2 and c_table.data_1 = 'yes' then a_table.youngsu_p end b_data
    , case when a_table.gubun = 2 and c_table.data_1 = 'yes' then a_table.youngsu_p*-1 end c_data
.........

이하 조인을 어떻게 해 주어야 할지 모르겠네요..
즉, a_table 의 구분값과.. b_table 이나, c_table 의 값을 가지고 a_table 의 값을 가지고 오고 싶습니다.

제가 아는 지식으로는 일반적인 조인 밖에 몰라서.. ㅠ.ㅠ
고수님들의 지식을 조금만 빌려 주셨으면 합니다. o(__)o 꾸벅

by 知音 [2011.01.04 12:56:30]
원하시는게 이게 맞는지 모르겠네요...

with a_table as (
select 1 arc_pk, 1 gubun, 100 youngsu_p from dual union all
select 1 , 2 , 200 from dual union all
select 2 , 2 , 200 from dual
), b_table as (
select 1 pk, 2 typ, 101 cat from dual
), c_table as (
select 1 pk, 'yes' data_1, '사과' data_2 from dual union all
select 2 , 'no' , '배' from dual
)
select a.gubun
, nvl(sum(case when a.gubun = 1 and b.typ = 2 then a.youngsu_p end), 0) a_data
, nvl(sum(case when a.gubun = 2 and c.data_1 = 'yes' then a.youngsu_p end), 0) b_data
, nvl(sum(case when a.gubun = 2 and c.data_1 = 'no' then a.youngsu_p * (-1) end), 0) c_data
from a_table a
, b_table b
, c_table c
where a.arc_pk = b.pk (+)
and a.arc_pk = c.pk (+)
group by a.gubun

by 사이베이스 [2011.01.04 13:02:16]
사이베이스라 테스트가 안되는데..
이렇게 하면 되나요? 궁금하네요;

SELECT
칼럼들
FROM A_TABLE A, B_TABLE B, C_TABLE C
WHERE A.PK = DECODE(A.GUBUN,1,B.PK,2,C.PK)

by 봉 [2011.01.04 13:43:19]
궁금해서 해봤는데 join을 할때 decode를 쓰면 안되네요
결과값이 많이 나와서 파악해보니
decode를 쓰면 a와 b가 조인이 된후 그 결과와 c테이블이 cross조인을 합니다
그리고 a와 c를 조인하고 다시 b테이블과 cross조인을 하고요
decode를 할 경우 대상 테이블과 조인을 한후 조인이 되지 않는 테이블에 대한
조건이 없게되기 때문에 알아서 cross조인을 해버리더군요

by 도가니 [2011.01.04 13:50:41]
이런방법을 많이 쓰지 않나 생각합니다.

with a_table as (
select 1 arc_pk, 1 gubun, 100 youngsu_p from dual union all
select 1 , 2 , 200 from dual union all
select 2 , 2 , 200 from dual ), b_table as (
select 1 pk, 2 typ, 101 cat from dual ), c_table as (
select 1 pk, 'yes' data_1, '사과' data_2 from dual union all
select 2 , 'no' , '배' from dual
)
select a.arc_pk, a.gubun, a.youngsu_p, b.pk bpk, b.typ, b.cat, null cpk, null data_1, null data_2
from a_table a, b_table b
where a.gubun = b.pk
and a.gubun=1
union all
select a.arc_pk, a.gubun, a.youngsu_p, null bpk, null typ, null cat, c.pk cpk, c.data_1, c.data_2
from a_table a, c_table c
where a.gubun = c.pk
and a.gubun=2;

by 질문자 [2011.01.04 13:53:58]
지음님.. 사이베이스님.. 봉님.. 진심으로 감사 드립니다.
지음님의 쿼리처럼 with로 해 봤었는데.. 안되길래 질문 올렸던건데..
다른점은 맨 아래.. a.arc_pk = b.pk 와 and a.arc_pk = c.pk 그리고.. group 이었는데.. outer(+) 조인을 안붙였군요.. 그 차이가 이렇게 클줄이야.. ㅠ.ㅠ
왜 그생각을 못했는지.. 1:1 매칭이다라고 생각만 했더니.. 두번째 조인만 되서 물어본거였거든요.. 즉, a.arc_pk = c.pk 이넘만 걸리더라구요.. 그래서 아.. 내가 뭔가 잘못했구나 해서 뭔지 몰라 올린거였는데.. 너무 너무 감사합니다.
그래도 결과값은 나왔는데.. plan 을 보니.. cost 가 좀 높기는 하네요.. ㅋ
사이베이스님것도 시도는 해 보았으나.. 함흥차사. ㅋ 봉님 말씀이 맞는것 같다는..^^; 모쪼록 세분의 지식이 저에게 큰 도움이 되었습니다. 감사합니다. o(__)o 꾸벅

by 질문자 [2011.01.04 14:02:20]
인사글 달고보니.. 도가니님의 글도 올라왔군요.. 감사합니다.
하지만.. 도가니님의 글처럼 할 경우.. 궂이 with 문은 필요 없을것 같네요.. 그냥 union all 만 해도 충분 합니다. 둘중 어떤것이 좀더 효율적일까 하다가.. with 문을 쓴건데.. 이유는 여기서는 예제일뿐 필드값이 좀 많아요..^^; 실제 쿼리는 약 3~400줄 정도 됩니다. 그걸 union all 로 묶고 sum 을 하려니.. 그냥 좀 아닌것 같아서.. select 문과, where 절을 좀 줄이는 방법이 없을까 해서.. 선택한거네요.. ^^
join 할 테이블 또한 좀 더 되거든요..
그럼 union all 만큼 중복해서.. 그리고.. select 문또한 중복해야 하다보니..^^
어쨌건.. 너무 너무 감사합니다. o(__)o 꾸벅

by 마농 [2011.01.04 15:18:13]
with 문에 대해서 오해들 많이 하시네요.
with 문을 그대로 사용하라고 적은게 아닙니다.
테스트 해보기 위한 임시자료 용도로 사용했을 뿐이죠.
실제 적용할때는 with문 빼고 실테이블에 적용하시면 됩니다.

SELECT *
FROM a_table a
, b_table b
, c_table c
WHERE DECODE(a.gubun, 1, a.arc_pk) = b.pk(+)
AND DECODE(a.gubun, 2, a.arc_pk) = c.pk(+)
;
댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입