>

직원이 있습니다->관리자 계층 구조이며 다음 쿼리를 사용합니다.

SELECT  EMP_ID, FIRST_NAME CONNECT_BY_ISCYCLE "CYCLE" FROM  MYTABLE CONNECT by NOCYCLE PRIOR MANAGER_EMP_ID = EMP_ID START WITH EMP_ID = '12345'

우리는 다음과 같은 결과를 얻고있다

12345   Nan 0
A12345  John 0
B12345  Dumble 0
C12345 Mark 0
D12345 Shady 0
E12345 Yenn 1

여기서 문제는 CEO (F12345)가 자신의 소유자 관리자이기 때문에 LOOP이 발생하여 테이블 끝에 CEO 레코드를 얻지 못하는 것입니다. 내 예상 결과는 다음과 같습니다.

12345   Nan 0
A12345  John 0
B12345  Dumble 0
C12345 Mark 0
D12345 Shady 0
E12345 Yenn 1
*F1345 Don*

LOOP 레코드도 검색 할 수있는 방법이 있습니까? 다른 방법이 없다면 아마도 두 번의 쿼리를 수행하고 CEO를 두 번째로 가져와야합니다.

모든 지침에 감사드립니다.

  • 답변 # 1

    CONNECT_BY_ISCYCLE=1 가있는 여분의 행을 얻기 위해 쿼리가 반환하는 것을 사용할 수 있습니다.

    WITH a AS
    (
    SELECT  EMP_ID, FIRST_NAME, MANAGER_EMP_ID, CONNECT_BY_ISCYCLE
    FROM  MYTABLE 
       CONNECT BY NOCYCLE
        PRIOR MANAGER_EMP_ID = EMP_ID 
        START WITH EMP_ID = '12345'
    )
    SELECT EMP_ID, FIRST_NAME
    FROM a
    UNION ALL
    SELECT m.EMP_ID, m.FIRST_NAME
    FROM MYTABLE m
      JOIN a
        ON a.MANAGER_EMP_ID = m.EMP_ID
    WHERE a.CONNECT_BY_ISCYCLE = 1 ;
    
    

    또는 재귀 CTE를 사용하십시오 :

    WITH a (EMP_ID, FIRST_NAME, MANAGER_EMP_ID) AS
    (
    SELECT  EMP_ID, FIRST_NAME, MANAGER_EMP_ID
    FROM  MYTABLE 
    WHERE EMP_ID = '12345'
    UNION ALL
    SELECT  m.EMP_ID, m.FIRST_NAME, m.MANAGER_EMP_ID
    FROM  MYTABLE m 
      JOIN a
        ON  a.MANAGER_EMP_ID = m.EMP_ID
        AND a.MANAGER_EMP_ID <> a.EMP_ID   -- to avoid the cycles
    )
    SELECT EMP_ID, FIRST_NAME
    FROM a ;
    
    

    재귀 CTE에서주기를 피하는 또 다른 방법은 CYCLE 를 사용하는 것입니다.  조항 (Oracle에서만 사용 가능) :

    WITH a (EMP_ID, FIRST_NAME, MANAGER_EMP_ID) AS
    (
    SELECT  EMP_ID, FIRST_NAME, MANAGER_EMP_ID
    FROM  MYTABLE 
    WHERE EMP_ID = 1
    UNION ALL
    SELECT  m.EMP_ID, m.FIRST_NAME, m.MANAGER_EMP_ID
    FROM  MYTABLE m 
      JOIN a
        ON  a.MANAGER_EMP_ID = m.EMP_ID
    )
    CYCLE MANAGER_EMP_ID 
      SET IS_CYCLE TO 'Y' DEFAULT 'N'
    SELECT EMP_ID, FIRST_NAME, IS_CYCLE
    FROM a ;
    
    

    SQLfiddle에서 테스트

    <시간>

    원래 쿼리에서 간단한 변경으로 여분의 행을 검색 할 수 있다는 것을 깨달았습니다 :

    SELECT  EMP_ID, FIRST_NAME, MANAGER_EMP_ID, CONNECT_BY_ISCYCLE
    FROM  MYTABLE 
       CONNECT BY NOCYCLE
         PRIOR MANAGER_EMP_ID = EMP_ID 
         AND PRIOR MANAGER_EMP_ID <> PRIOR EMP_ID 
                                     -- if she's a manager
                                     -- don't try to connect her with superiors
       START WITH EMP_ID = '12345' ;
    
    

  • 이전 sql server 2008 - 이전 또는 다음 행을 두 열의 현재 행과 비교하려면 어떻게합니까?
  • 다음 SQL Server 2012 Developer Edition을 SQL Server 2014로 업그레이드 하시겠습니까?