오라클 쿼리 초보적인.. 질문드립니다! 0

by 밸런스 [Oracle 기초] [2024.08.18 14:20:31]


데이터는 아래와 같이

CodeA 테이블과 CodeB 테이블이 있습니다.

CodeA 테이블에 CodeB테이블의 없는 Code_ID값을 추가하고 싶습니다.. 말로도 잘 풀지 못하겠..네요

결과값이 아래처럼 나와야 하는데 잘 모르겠습니다. 도움을 부탁드립니다.

---------결과값--------

CODE_A_PK CODE_ID CODE_NM 설명
PK1 C 코드C

CodeA : PK1 행 기준

CodeB 테이블에 CodeA 테이블 code_id 값인 A가 있음으로 C만 추가

PK2 A 코드A

CodeA : PK2 행 기준

CodeB 테이블에 CodeA 테이블의 code_id 값인 A,C가 없어서 A,C 추가

PK2 C 코드C 위와 동

 

----------- 데이터 ---------- ------

With CodeA as (
Select 'pk1' as code_a_pk, 'A' as code_id, '코드A' as code_nm from dual union all
Select 'pk2' as code_a_pk, 'B' as code_id, '코드B' as code_nm from dual
),
CodeB as (
Select 'pk1' as code_b_pk, 'A' as code_id, '코드A' as code_nm from dual union all
Select 'pk2' as code_b_pk, 'C' as code_id, '코드C' as code_nm from dual
),
Select *
From   CodeA, CodeB

 

by 마농 [2024.08.20 14:53:03]

뭔본 대비 결과가 틀린게 아닌지?
pk2, C 만 추가하면 되는 것 아닌가요?
최종 결과
pk1, A - 변동없음
pk2, B - 변동없음
pk2, C - 추가


by 밸런스 [2024.08.20 15:22:04]

아 제가 설명을 잘 못해서 죄송합니다.

CodeB에 있는 CODE_ID 에 새로운 값이 추가되면

CodeA에 CodeB에서 추가된 CODE_ID 값을 찾아서 있으면 pass, 없으면 추가, 기존 테이블에 값이 추가 되는건 아니라 새로운 표를 만드는 로직입니다..

 

기존에 CodeA 에 'A', 'B'만 존재하다가

CodeB 에 'A','C'가 추가 되었을 시

- CodeA 의 pk1, A는 CodeB에서 추가한 A와 겹쳐서 pass 이고 C는 없으니 추가

- CodeA 의 pk2, B는 CodeB에서 추가한 A,C 가 없어서 새로운 표에 추가..

 

이런 로직인데 설명도 두서없이 죄송합니다.


by 우주민 [2024.08.20 15:43:41]

CodeB에 있는 CODE_ID 에 새로운 값이 추가되면

CodeA에 CodeB에서 추가된 CODE_ID 값을 찾아서 있으면 pass, 없으면 추가.

이런 로직에서 CodeB 테이블의 pk 값은 비교대상이 아닌건가요?

 

아마도 지금 설명하신 로직은

1. CodeB 테이블에 A, C 값이 추가됨(pk 상관 없이)

2. CodeA 테이블의 pk1 에서 A 값이 있으므로 C값이 추가

3. CodeA 테이블의 pk2 에서 A, C 값이 없으므로 둘다 추가 

인듯 싶은데, 그렇다면 CodeB 테이블의 pk 값은 사용되지 않는 값인듯 합니다

 


by 우주민 [2024.08.20 15:47:41]
With CodeA as (
Select 'pk1' as code_a_pk, 'A' as code_id, '코드A' as code_nm from dual union all
Select 'pk2' as code_a_pk, 'B' as code_id, '코드B' as code_nm from dual
),
CodeB as (
Select 'pk1' as code_b_pk, 'A' as code_id, '코드A' as code_nm from dual union all
Select 'pk2' as code_b_pk, 'C' as code_id, '코드C' as code_nm from dual
)
Select a.code_a_pk, b.code_id, b.code_nm
From   CodeA a
,CodeB b
where a.code_id <> b.code_id
order by 1, 2

 


by 우주민 [2024.08.20 16:21:08]

수정본 / 위의 쿼리는 codeA 테이블의 code_a_pk 값에 대해 code_id 값이 1개만 배정될때 정상 동작 하네요....

With CodeA as (
Select 'pk1' as code_a_pk, 'A' as code_id, '코드A' as code_nm from dual union all
Select 'pk1' as code_a_pk, 'C' as code_id, '코드C' as code_nm from dual union all -- 테스트를 위한 추가행
Select 'pk2' as code_a_pk, 'B' as code_id, '코드B' as code_nm from dual
)
,CodeB as (
Select 'pk1' as code_b_pk, 'A' as code_id, '코드A' as code_nm from dual union all
Select 'pk2' as code_b_pk, 'C' as code_id, '코드C' as code_nm from dual
)
,temp as (
Select 
a.code_a_pk, b.code_id, b.code_nm
From   CodeA a 
inner join (select distinct code_id, code_nm from CodeB) b
on a.code_id = b.code_id
)
select a.code_a_pk, b.code_id, b.code_nm
from CodeA a
left outer join (select distinct code_id, code_nm from CodeB) b
on a.code_id <> b.code_id
where (a.code_a_pk, b.code_id) not in (select t.code_a_pk, t.code_id from temp t)
order by 1, 2

 

뭔가 많이 복잡해졌지만....


by 밸런스 [2024.08.20 16:22:30]

넵 맞습니다..

풀 조인하고 일치하지 않으면 으로도 되는 것이군용.

감사합니다.

성능상 풀조인해도 크게 문제되지 않을까요?


by 마농 [2024.08.20 16:33:06]

B에서 pk 를 따로 입력 받으면서 사용하지 않는 것이 맞는지? 의문입니다.


by 밸런스 [2024.08.20 16:41:03]

넵 CodeB의 pk는 무의미한 값입니다.

실제로는 없는 값.. 입니다.


by 마농 [2024.08.20 16:48:26]
WITH CodeA AS
(
SELECT 'pk1' code_a_pk, 'A' code_id, '코드A' code_nm FROM dual
UNION ALL SELECT 'pk2', 'B', '코드B' FROM dual
)
, CodeB AS
(
SELECT 'A' code_id, '코드A' code_nm FROM dual
UNION ALL SELECT 'C', '코드C' FROM dual
)
SELECT a.code_a_pk
     , b.code_id
     , b.code_nm
  FROM CodeB b
  LEFT JOIN CodeA a
  PARTITION BY (a.code_a_pk)
    ON b.code_id = a.code_id
 WHERE a.code_id IS NULL
;

 


by 우주민 [2024.08.20 16:56:24]

와.... 한참 간소화 쿼리 만들고 있는데... join - partition 은 생각 못하고 있었네요..

제 나름 간소화한 쿼리 입니다.

Select 
a.code_a_pk, b.code_id, b.code_nm
From (select distinct  code_a_pk from CodeA) a 
inner join (select distinct code_id, code_nm from CodeB) b
left outer join CodeA c
on a.code_a_pk = c.code_a_pk
and b.code_id = c.code_id
where c.code_id is null
order by 1, 2

 


by 마농 [2024.08.20 17:20:42]

INNER JOIN 만 CROSS JOIN 으로 바꾸면 의미가 명확해질 듯 합니다.
PARTITION JOIN 기능이 없다면? 이렇게 하는게 맞습니다.
B 에 중복은 없다고 가정하고 Distinct 는 빼도 될 듯 하네요.


by 우주민 [2024.08.20 17:36:54]

네. cross join 이 제가 테스트하는 웹 사이트에서 적용이 안되어 조건없는 inner 로 처리했네요.

덕분에 좋은 방법 하나 배워갑니다.


by 밸런스 [2024.08.20 17:57:04]

마농님,우주민님 도움주셔서 감사합니다.!!

댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입