MS SQL 계층형(CTE) 쿼리 앞에 IN 절 사용방법 또는 함수 리턴값 다중 ROW 문의 1 3 3,711

by kento [SQLServer] 계층형 CTE IN 함수 리턴값 다중 ROW [2019.01.02 17:23:00]


안녕하세요 

ORACLE 개발하다가 MS SQL 로 쿼리 짤라니까

안되는 점이 너무 많네요 

도움좀 받고 싶어서 글을 남기게 되었습니다.

혼자 찾아 보는것도 지치네요 ....

 

오라클 같으면 제약 없이 계층형(CTE) 조건문에 쓰는데

MS SQL은 WITH 위에 조건이 있으면 안되는거같더라구요 

2가지 방법으로 접근해 봤는데 

다른방법 있으면 지도좀 부탁드립니다.


-- 방법 1

SELECT H.ID ,  E.ID 

FROM USER H, ERP E

WHERE H.USE_YN=1 AND E.CNT > 0

UNION ALL

SELECT H.ID ,  E.ID 

FROM USER H, ERP E

WHERE E.ID IN 

(

-- 이부분이 안됩니다 ㅠ.ㅠ MS SQL 에서는 WITH 문 위에 다른것들을 못넣더라구요...

-- 이 위에 또 UNION ALL 절이 있어서 WITH 문을 앞으로 뺄수가 없어요 ... 

  WITH TREE

  AS ( SELECT ID FROM ERP WHERE ID = H.ID -- (상위에 값을 START WITH)

  UNION ALL

  SELECT ID FROM ERP AS CHILD , TREE PARENT

   WHERE CHILID.PARENTID = PARENT.ID )

  SELECT ID FROM TREE

)



--  방법2

SELECT H.ID ,  E.ID

FROM USER H, ERP E

WHERE H.USE_YN=1 AND E.CNT > 0

UNION ALL

SELECT H.ID ,  E.ID

FROM USER H, ERP E

WHERE E.ID IN

(

-- 함수를 만들어서 호출하는 방법.  함수는 CTE문

-- 하지만 리턴값이 다중 ROW인데 첫번째 값만 리턴네요 ;; 함수는 바로 밑에 써볼께요 

dbo.treeCte(H.id) 

)

-- 함수문

CREATE FUNCTION treeCte (@ID NUMERIC)

RETURNS NUMERIC(8)  -- 다중 ROW 값으로 리턴 받으려면 어떻게 선언해야되는지 모르겠네요 .. NUMERIC 으로 선언하니 첫번째 값만 리턴합니다..

AS

BEGIN

DECLARE @V_RETURN NUMERIC(8)

WITH TREE

  AS ( SELECT ID FROM ERP WHERE ID = @ID

  UNION ALL

  SELECT ID FROM ERP AS CHILD , TREE PARENT

   WHERE CHILID.PARENTID = PARENT.ID )

  SELECT @V_RETURN=ID FROM TREE

  RETURN @V_RETURN;

END

 

by 마농 [2019.01.03 09:21:02]

쿼리 중간에서 특정 ID 를 시작조건으로 계층 전개 하지 마시고
쿼리 시작할 때 모든 ID 를 시작조건으로 계층 전개 하세요.
그 후에 조인을 하든 IN 조건으로 쓰던 하면 될 듯 하네요.
그리고, union 위쪽 쿼리에 user 와 erp 사이에 조인 조건이 없는거 맞나요? 이상하네요?

WITH tree AS
(
SELECT id root_id
     , id
  FROM erp
 UNION ALL
SELECT p.root_id
     , c.id
  FROM tree p
 INNER JOIN erp c
    ON p.id = c.parentid
)
SELECT h.id
     , t.id
  FROM user h
 INNER JOIN tree t
    ON h.id = t.root_id
;

 


by kento [2019.01.03 21:23:50]

답변 감사합니다 ^^

진심으로 머리 숙여 감사드립니다 ^^

한수 배워갑니다 절대 안까먹을거같네요 ㅋㅋ

 

MS-SQL 에서 계층형 쿼리에서

타 테이블과 조인하거나 UNION 쓰려면

WITH 가 맨 위에 선언되어야 햇네요 .. (아직도 적응이 안되네요 ;; )

저와 같이 삽질하지말라고 얕은 지식이지만 그래도 공유 합니다 ;;


WITH tree AS

(

SELECT id root_id , id

  FROM erp

 UNION ALL 

SELECT p.root_id , c.id

  FROM tree p

 INNER JOIN erp c

  ON p.id = c.parentid

) SELECT t.rootid , t.id from tree t  -- 요롷게요 ㅋㅋ  이 밑에서 오라클과 같이 타 테이블과 조인해서 쓸수 있더라구요

WHERE t.id in (SELECT ID FROM XXXX )

UNION ALL  -- 이 밑으로 UNION 도 쓸수 있구요

SELECT ROOTID, ID FROM XXXX ; 





-- 2개의 계층형 쿼리를 맨위에 선언해서 밑에서 조인 할수도 있어요 ~

WITH tree1 AS

(

SELECT id root_id , id

  FROM erp

 UNION ALL 

SELECT p.root_id , c.id

  FROM tree p

 INNER JOIN erp c

  ON p.id = c.parentid

) ,

tree2 AS -- 여기에 다른 계층형 쿼리를 한번 더 선언해서 밑에서 조인걸면 될거같아요

(

SELECT id root_id , id

  FROM erp

 UNION ALL 

SELECT p.root_id , c.id

  FROM tree p

 INNER JOIN erp c

  ON p.id = c.parentid

)

SELECT t.rootid , t.id from tree1 t  

WHERE t.id in (SELECT ID FROM XXXX )

UNION ALL  

SELECT t2.rootid, t2.id FROM xxx h INNER JOIN tree2 t2

 ON h.id = t2.id;


 


by kento [2019.01.03 11:28:57]

답변 감사합니다.

union 위쪽 쿼리에 조인 조건은 있는데 손으로 직접쓰다보니 누락되었네요 .. ;; 

선답변 후코팅 ! 한번 해보겠습니다 ^^

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