簡體   English   中英

SQL Server中的遞歸CTE查詢

[英]Recursive CTE query in SQL Server

我已經在此站點上查看了許多遞歸CTE示例,並且嘗試將其應用於我自己的數據。 與大多數示例相比,我似乎擁有更多的聯接,但我認為我能到達那里。 我需要幫助的問題是我收到一條錯誤消息:

聲明終止。 在語句完成之前,最大遞歸100已用盡。

我已經運行了CTE的第一條select語句,並且我已經反復運行了第二條select語句(具有不同的實際職位代碼),並且對於該員工有六個級別,因此我看不到為什么會出錯。

我的一個懷疑領域是我必須應用標准'relationship_type_id = 0',因為這是'Reports To'關系類型。 我曾嘗試將其設為左外部聯接,但不允許這樣做。 這意味着我不會使用此查詢來獲得最高級別的經理(即本身沒有經理的人)。

我已經在下面發布了代碼,任何幫助將不勝感激。

WITH EmployeeHierarchy (EmployeeID, LastName, FirstName, PositionCode, ReportsTo, HierarchyLevel) AS 
(
   SELECT 
      p.employee_id as EmployeeID,
      p.last_name as LastName,
      p.first_name as FirstName,
      pos.position_code as PositionCode,
      r.to_position_code as ReportsTo,
      1 as HierarchyLevel
   FROM 
       --JOIN: Personal details
       dbo.person p
   --JOIN: Employment links a person to a post (could have more than one)
   INNER JOIN 
       dbo.employment e ON e.employee_id = p.employee_id
   --JOIN: details of the position held
   INNER JOIN 
       dbo.position pos ON pos.position_code = e.position_code
   --JOIN: Relationships between the positions, one position reports to another position etc.
   --      There are several 'relationship types', we are only interested in relationship_type_id = 0 
   --      as this is the 'Reports to' relationship code.  Others types include 'Managed by' etc.
   INNER JOIN 
       dbo.relationship r ON r.from_position_code = pos.position_code AND r.relationship_type_id = 0
   WHERE 
       --CRITERIA: Use my employee Id as a starting point for testing
       p.employee_id = '10076395'

   UNION ALL

   -- Recursive step
   SELECT 
       p2.employee_id as EmployeeID,
       p2.last_name as LastName,
       p2.first_name as FirstName,
       pos2.position_code as PositionCode,
       r2.to_position_code as ReportsTo,
       eh.HierarchyLevel + 1 AS HierarchyLevel
   FROM 
       dbo.person p2
   INNER JOIN 
       dbo.employment e2 ON e2.employee_id = p2.employee_id
   INNER JOIN 
       dbo.position pos2 ON pos2.position_code = e2.position_code
   INNER JOIN 
       dbo.relationship r2 ON r2.from_position_code = pos2.position_code AND r2.relationship_type_id = 0
   --JOIN: Link this query back to the base query
   INNER JOIN 
       EmployeeHierarchy eh ON r2.from_position_code = eh.PositionCode
)
SELECT *
FROM EmployeeHierarchy
ORDER BY HierarchyLevel, LastName, FirstName 

請試試 :

WITH EmployeeHierarchy (EmployeeID, LastName, FirstName, PositionCode, ReportsTo, HierarchyLevel) AS 
(
SELECT 
    p.employee_id as EmployeeID,
    p.last_name as LastName,
    p.first_name as FirstName,
    pos.position_code as PositionCode,
    r.to_position_code as ReportsTo,
    1 as HierarchyLevel
FROM 
    --JOIN: Personal details
    dbo.person p

    --JOIN: Employment links a person to a post (could have more than one)
    INNER JOIN dbo.employment e
    ON e.employee_id = p.employee_id

    --JOIN: details of the position held
    INNER JOIN dbo.position pos 
    ON pos.position_code = e.position_code

    --JOIN: Relationships between the positions, one position reports to another position etc.
    --      There are several 'relationship types', we are only interested in relationship_type_id = 0 
    --      as this is the 'Reports to' relationship code.  Others types include 'Managed by' etc.
    INNER JOIN dbo.relationship r
    ON  r.from_position_code = pos.position_code
        and r.relationship_type_id = 0
WHERE 
    --CRITERIA: Use my employee Id as a starting point for testing
    p.employee_id = '10076395'

UNION ALL
-- Recursive step
SELECT 
    p2.employee_id as EmployeeID,
    p2.last_name as LastName,
    p2.first_name as FirstName,
    pos2.position_code as PositionCode,
    r2.to_position_code as ReportsTo,
    eh.HierarchyLevel + 1 AS HierarchyLevel
 FROM 
    dbo.person p2

    INNER JOIN dbo.employment e2
    ON e2.employee_id = p2.employee_id

    INNER JOIN dbo.position pos2 
    ON pos2.position_code = e2.position_code

    INNER JOIN dbo.relationship r2
    ON  r2.from_position_code = pos2.position_code
        and r2.relationship_type_id = 0

    --JOIN: Link this query back to the base query
    INNER JOIN EmployeeHierarchy eh 
    ON r2.from_position_code = eh.ReportsTo
)
SELECT *
FROM EmployeeHierarchy
ORDER BY HierarchyLevel, LastName, FirstName 

試試看。

我已將復雜的聯接移至單獨的CTE,以保持遞歸部分盡可能簡潔。 如果沒有其他方法,這種方法應該可以幫助您查明問題。

; WITH employees AS (
  SELECT person.employee_id
       , person.last_name
       , person.first_name
       , position.position_code
       , relationship.to_position_code
  FROM   dbo.person
   INNER
    JOIN dbo.employment
      ON employment.employee_id = person.employee_id
   INNER
    JOIN dbo.position
      ON position.position_code = employment.position_code
   INNER
    JOIN dbo.relationship
      ON relationship.from_position_code = position.position_code
     AND relationship.relationship_type_id = 0
)
, recursive_bit AS (
  SELECT employee_id
       , last_name
       , first_name
       , position_code
       , to_position_code
  FROM   employees
  WHERE  employee_id = '10076395'

    UNION ALL

      SELECT employees.employee_id
           , employees.last_name
           , employees.first_name
           , employees.position_code
           , employees.to_position_code
      FROM   recursive_bit
       INNER
        JOIN employees
          ON employees.position_code = recursive_bit.to_position_code
)
SELECT *
FROM   recursive_bit

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM