두개의 테이블을 join할때 여러 조건 걸기 0 8 2,657

by 마카히로 [Oracle 기초] join 조건 [2023.02.17 14:44:14]


안녕하세요!

 

날짜

내용  

1월1일 의뢰
1월2일 의뢰(*완료가안와서재촉)
1월3일 완료1
1월4일 의뢰
1월5일 완료2
1월6일 완료3(완료했지만 굳이다시완료)
1월7일 의뢰

 

위와 같이 '의뢰'를 여러번하고, '완료'도 여러번 일어나는 테이블이 있을때,

(완료옆에 1,2는 설명을 쉽게하고자 제가 임의로 넣은 숫자입니다^^;)

아래와 같은 결과물을 만들고 싶습니다.

 

결과물

의뢰날짜   완료날짜  
1월1일   1월3일  
1월4일   1월5일  
1월7일   NULL  

 

 

제가 생각한 방법은 테이블을 의뢰테이블 A, 완료테이블 B로 분리하여

 

 

의뢰 테이블 A를 기준으로하고,

완료테이블B 을 LEFT 조인하면서

 

★질문 1번 - JOIN 조건문을 아래와 같이 짜고싶습니다!!!!

1 )의뢰일보다 뒤에 날짜인 완료건들 중에서

2) 그중에서 제일 작은 완료날짜를 조인하자

 

----------질문 후 답변을 기다리는 동안 ChatGPT 도움받아 아래와 같이  짜봤는데 안돌아가네요 ㅠㅜ 비문인가.... ------------


SELECT A.의뢰,A.의뢰날짜, min(B.완료날짜)
from

(select 날짜 as 의뢰날짜, 내용
from 테이블
where 내용 = '의뢰'
) A

left join

(select 날짜 as 완료날짜,내용
from 테이블
where 내용 ='완료'
) B on B.완료날짜 > A.의뢰날짜 group by A.의뢰

 


 

--------------------------------------------------------------------------------------------------------------------

 

조인이 잘 될 경우,

1/1일 의뢰에도 - 1/3일 (완료1)이 붙고

1/2일 의뢰에도 -1/3일 (완료1)이 붙게 될텐데

 

이때 중복을 '완료값'이 중복인걸 제거하면 될것같거든요.

★ 질문 2-1번

DISTICT나 GROUP BY로 완료날짜가 중복인 것들 중 의뢰날짜가 빠른 것만 남기는 DISTICT, GROUP BY를 할수 있을까요?

★ .2-2번 안된다면..  - ROW_NUBER () OVER (PARTION BY 진행단계완료 ORDER BY 날짜 -- 의뢰날짜겟죠?) 에서 1번만 남기면 될까요? 

 

 

 

고수님들 .. 도움 꼭 부탁드립니다 ㅜㅜ

by 우리집아찌 [2023.02.17 15:44:31]

현재 테이블 상태로도 결과값을 만들수 있을것 같은데요.

환자 , 의뢰/완료 구분은 없나요?


by 마카히로 [2023.02.17 15:49:39]

앗 그런가요? 의뢰/완료 구분이 어떤 의미 인지 이해를 못했습니다~ 진행단계라는 컬럼안에 의뢰,완료가 값 형태로 한테이블 안에 있습니다! 쌓인 행들의 구별은 날짜,시간이구요!

 

(현재 테이블에서 완료 옆에 숫자는 제가 설명을 위해 임의로 붙인 숫자입니다 ;;^^)


by 우리집아찌 [2023.02.17 16:03:46]

의뢰 최초값이랑 완료 최종값을 가져오시는것 같은데요.

텍스트값 형태로 있으면 구분이 어려워서요.

코드로 되어있지 않나 싶어서 말씀드린겁니다.


by 마카히로 [2023.02.17 16:06:28]

아 맞습니다 코드로 되어있습니다

  varchar 형태로 의뢰는 20 완료는 30 입니다

 


by 마카히로 [2023.02.17 16:08:26]

다만, 의뢰도 완료오기전에 여러개가 있다면 최초값이고

완료도 여러개 완료가 왔다면 해당 의뢰 이후에 최초값입니다 그래서 

조인의 조건을 의뢰 (1월4일) 이후 완료 (1월5일과 6일) 중에 제일 작은 1월5일 값으로 조인하는 조건을 찾고자합니다~


by 우리집아찌 [2023.02.17 18:44:13]
-- 손으로 옮겨적어서 오타가 있을수 있어요
with t as (
select '1월1일' dt , '20' gb , '의뢰'  TXT FROM DUAL UNION ALL 
select '1월2일' dt , '20' gb , '의뢰'  TXT FROM DUAL UNION ALL 
select '1월3일' dt , '30' gb , '완료'  TXT FROM DUAL UNION ALL 
select '1월4일' dt , '20' gb , '의뢰'  TXT FROM DUAL UNION ALL 
select '1월5일' dt , '30' gb , '완료'  TXT FROM DUAL UNION ALL 
select '1월6일' dt , '30' gb , '완료'  TXT FROM DUAL UNION ALL 
select '1월7일' dt , '20' gb , '의뢰'  TXT FROM DUAL  

)

SELECT GB
          , MIN(CASE WHEN GB1 = '20' THEN DT END ) V1
          , MIN(CASE WHEN GB1 = '30' THEN DT END ) V1
     FROM (
                   SELECT SUM(CASE WHEN GB1 < GB2 THEN 1 ELSE 0 END ) OVER(ORDER BY DT ) GB
                 , AA.*
            FROM ( SELECT GB GB1
                                     , LAG(GB) OVER(ORDER BY DT ) GB2
                                     , A.DT
                               FROM T A 
                         ) AA
                     ) AAA
GROUP BY GB
ORDER BY GB

 


by 마카히로 [2023.02.20 08:50:52]

간단해보이면서도 이해하기 조금 어렵네요 답변 감사합니다~


by 케를로스 [2023.02.20 10:52:04]

의뢰 테이블에 최종완료일 컬럼 넣어주는것으로 역정규화 하는것도 괜찮아 보이네요 

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