쿼리 작성질문 2 5 953

by DeSSa [SQL Query] [2021.02.23 15:11:22]


안녕하세요. 계속 고민해 봐도 답이 나오지 않아 도움을 받고자 질문 드립니다!!

미리 감사 드립니다.!

 

[데이터셋]

ID star1 start2
1 henny han
2 hw han
3 hunkim henny
4 hw henny
5 hunkim hw
6 hunkim lucy
7 hunkim han

[조건]

1. star1이든 star2든 한번이라도 출력된 이름은 두번 출력 하지 않게
2. star1과 start2는 연관이 없는 테이블이고
3. star1에 henny가 언급되어서 선정 되었다면 star2 컬럼에서도 henny 가 존재 하면 안됨
4. 순서는 위에서 아래로 순차적
 

[기대결과값] - 노란색 row만 도출

ID star1 star2
1 henny han
2 hw han
3 hunkim henny
4 hw henny
5 hunkim hw
6 hunkim lucy
7 hunkim han

 

 

 

 

 

 

 

by 마농 [2021.02.23 16:35:10]
WITH t AS
(
SELECT 1 id, 'henny' star1, 'han' star2 FROM dual
UNION ALL SELECT 2, 'hw'    , 'han'   FROM dual
UNION ALL SELECT 3, 'hunkim', 'henny' FROM dual
UNION ALL SELECT 4, 'hw'    , 'henny' FROM dual
UNION ALL SELECT 5, 'hunkim', 'hw'    FROM dual
UNION ALL SELECT 6, 'hunkim', 'lucy'  FROM dual
UNION ALL SELECT 7, 'hunkim', 'han'   FROM dual
)
, t1(id, star1, star2, x, flag) AS
(
SELECT id, star1, star2
     , CAST('/'||star1||'/'||star2||'/' AS VARCHAR(999)) x
     , 1 flag
  FROM t
 WHERE id = 1
 UNION ALL
SELECT b.id, b.star1, b.star2
     , a.x ||
       CASE WHEN INSTR(a.x, '/'||b.star1||'/')
               + INSTR(a.x, '/'||b.star2||'/') = 0
            THEN b.star1||'/'||b.star2||'/'
             END x
     , CASE WHEN INSTR(a.x, '/'||b.star1||'/')
               + INSTR(a.x, '/'||b.star2||'/') = 0
            THEN 1 ELSE 0 END flag
  FROM t1 a
     , t  b
 WHERE b.id = a.id + 1
)
SELECT *
  FROM t1
 WHERE flag = 1
;

 


by DeSSa [2021.02.23 16:47:15]

와 진짜.. 넘사벽이세요.. 정말 감사합니다!


by 동동동 [2021.02.24 10:23:44]
, t1(id, star1, star2, x, flag) AS
(
SELECT id, star1, star2
     , CAST('/'||star1||'/'||star2||'/' AS VARCHAR(999)) x
     , 1 flag
  FROM t
 WHERE id = 1                         -- > 1
 UNION ALL
SELECT b.id, b.star1, b.star2
     , a.x ||
       CASE WHEN INSTR(a.x, '/'||b.star1||'/')
               + INSTR(a.x, '/'||b.star2||'/') = 0
            THEN b.star1||'/'||b.star2||'/'
             END x
     , CASE WHEN INSTR(a.x, '/'||b.star1||'/')
               + INSTR(a.x, '/'||b.star2||'/') = 0
            THEN 1 ELSE 0 END flag
  FROM t1 a            -- > 2.
     , t  b
 WHERE b.id = a.id + 1         --> 3

 

마농님 쿼리가 이해가 안되서 문의 드립니다..ㅠㅠ

저기서 1번에서 무조건 첫번째줄은 중복이 안될거니 가져오고..

UNION ALL 부분이 이해가 안되는데요.. 

2번에서 t1이 1번의 첫줄 데이터를 가져오는 건가요? 그럼 3번에서는 2번째줄 하나만 일텐데..마치 for문이 실행되듯 a.id+1씩을 반복해서..전체  Row를 가져오네요??

From 절의 t1 (2번) 이 어떤 데이터를 의미 한건지요??

 

항상 감사드립니다...^^


by 마농 [2021.02.24 12:25:46]

재귀쿼리입니다. Recursive SQL : Oracle 11G R2
 WITH 절에서 정의한 명칭을 WITH 절 안에서 사용하여 재귀적으로 호출되는 구조입니다.
11G 부터는 이 재귀구문으로 계층쿼리를 작성할 수 있습니다. 11G 이전 Start With Connect By
 UNION 상단에서 최상위 노드를 추출하고 1 레벨
UNION 하단에서 1레벨과 조인하여 2레벨을 추출합니다.
추출된 2레벨과 조인하여 3레벨을 추출하고
이러한 과정이 반복적으로 수행되어 하위 레벨을 이어 나갑니다.


by 동동동 [2021.02.24 14:43:23]

마농님 답변 감사드립니다...^^

오늘도 마농님 덕분에 하나 또 알고 가네요...정말 감사드립니다...

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