Sqlserver
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Sqlserver

Ví dụ về CTE và đệ quy của SQL Server

Tôi chưa kiểm tra mã của bạn, chỉ cố gắng giúp bạn hiểu cách nó hoạt động trong nhận xét;

WITH
  cteReports (EmpID, FirstName, LastName, MgrID, EmpLevel)
  AS
  (
-->>>>>>>>>>Block 1>>>>>>>>>>>>>>>>>
-- In a rCTE, this block is called an [Anchor]
-- The query finds all root nodes as described by WHERE ManagerID IS NULL
    SELECT EmployeeID, FirstName, LastName, ManagerID, 1
    FROM Employees
    WHERE ManagerID IS NULL
-->>>>>>>>>>Block 1>>>>>>>>>>>>>>>>>
    UNION ALL
-->>>>>>>>>>Block 2>>>>>>>>>>>>>>>>>    
-- This is the recursive expression of the rCTE
-- On the first "execution" it will query data in [Employees],
-- relative to the [Anchor] above.
-- This will produce a resultset, we will call it R{1} and it is JOINed to [Employees]
-- as defined by the hierarchy
-- Subsequent "executions" of this block will reference R{n-1}
    SELECT e.EmployeeID, e.FirstName, e.LastName, e.ManagerID,
      r.EmpLevel + 1
    FROM Employees e
      INNER JOIN cteReports r
        ON e.ManagerID = r.EmpID
-->>>>>>>>>>Block 2>>>>>>>>>>>>>>>>>
  )
SELECT
  FirstName + ' ' + LastName AS FullName,
  EmpLevel,
  (SELECT FirstName + ' ' + LastName FROM Employees
    WHERE EmployeeID = cteReports.MgrID) AS Manager
FROM cteReports
ORDER BY EmpLevel, MgrID

Ví dụ đơn giản nhất về CTE đệ quy Tôi có thể nghĩ đến để minh họa hoạt động của nó là;

;WITH Numbers AS
(
    SELECT n = 1
    UNION ALL
    SELECT n + 1
    FROM Numbers
    WHERE n+1 <= 10
)
SELECT n
FROM Numbers

Q 1) giá trị của N đang tăng lên như thế nào. nếu giá trị được gán cho N mọi lúc thì giá trị N có thể được tăng lên nhưng chỉ giá trị N lần đầu tiên được khởi tạo .

A1: Trong trường hợp này, N không phải là một biến. N là một bí danh. Nó tương đương với SELECT 1 AS N . Nó là một cú pháp của sở thích cá nhân. Có 2 phương pháp chính của các cột răng cưa trong CTE trong T-SQL . Tôi đã đưa vào tương tự của một CTE đơn giản trong Excel để thử và minh họa theo cách quen thuộc hơn về những gì đang xảy ra.

--  Outside
;WITH CTE (MyColName) AS
(
    SELECT 1
)
-- Inside
;WITH CTE AS
(
    SELECT 1 AS MyColName
    -- Or
    SELECT MyColName = 1  
    -- Etc...
)

Q 2) bây giờ ở đây về CTE và đệ quy của tương đối nhân viên tại thời điểm tôi thêm hai người quản lý và thêm một vài nhân viên nữa dưới người quản lý thứ hai, sau đó sự cố bắt đầu. tôi muốn hiển thị chi tiết người quản lý đầu tiên và trong các hàng tiếp theo sẽ chỉ có những chi tiết nhân viên đó những người là cấp dưới của người quản lý đó

A2:

Mã này có trả lời câu hỏi của bạn không?

--------------------------------------------
-- Synthesise table with non-recursive CTE
--------------------------------------------
;WITH Employee (ID, Name, MgrID) AS 
(
    SELECT 1,      'Keith',      NULL   UNION ALL
    SELECT 2,      'Josh',       1      UNION ALL
    SELECT 3,      'Robin',      1      UNION ALL
    SELECT 4,      'Raja',       2      UNION ALL
    SELECT 5,      'Tridip',     NULL   UNION ALL
    SELECT 6,      'Arijit',     5      UNION ALL
    SELECT 7,      'Amit',       5      UNION ALL
    SELECT 8,      'Dev',        6   
)
--------------------------------------------
-- Recursive CTE - Chained to the above CTE
--------------------------------------------
,Hierarchy AS
(
    --  Anchor
    SELECT   ID
            ,Name
            ,MgrID
            ,nLevel = 1
            ,Family = ROW_NUMBER() OVER (ORDER BY Name)
    FROM Employee
    WHERE MgrID IS NULL

    UNION ALL
    --  Recursive query
    SELECT   E.ID
            ,E.Name
            ,E.MgrID
            ,H.nLevel+1
            ,Family
    FROM Employee   E
    JOIN Hierarchy  H ON E.MgrID = H.ID
)
SELECT *
FROM Hierarchy
ORDER BY Family, nLevel

Một sql khác với cấu trúc cây

SELECT ID,space(nLevel+
                    (CASE WHEN nLevel > 1 THEN nLevel ELSE 0 END)
                )+Name
FROM Hierarchy
ORDER BY Family, nLevel


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Làm cách nào để kiểm tra xem một cột có tồn tại trong bảng SQL Server hay không?

  2. Giới hạn phiên người dùng đồng thời cho một đăng nhập cụ thể trong SQL Server

  3. Cách tạo bảng từ kết quả truy vấn chọn trong SQL Server 2008

  4. Tại sao truyền từ float sang varchar được làm tròn trong SQL Server?

  5. SQL Server:sử dụng tham số trong TẠO CƠ SỞ DỮ LIỆU