zoukankan      html  css  js  c++  java
  • SQL Server递归实例

    例子一

    -- =============================================
    -- 根据EID返回其下属的EID,Layer=1表示直接下属,NULL返回所有下属
    -- select EID FROM F_Team_GetSubordinate(2,NULL)
    -- =============================================
    CREATE FUNCTION F_Team_GetSubordinate(
    @EID INT,
    @Layer INT)
    RETURNS @tb TABLE (EID INT,NameCN varchar(50),SupervisorEID INT,Layer INT)
    AS
    BEGIN
    
    ;WITH CTE AS
    (
    SELECT EID,NameCn,SupervisorEID,0 as Layer FROM TCFG_Employee WHERE EID=@EID
    UNION ALL
    SELECT A.EID,A.NameCn,A.SupervisorEID,Layer=layer+1 FROM TCFG_Employee A
    JOIN CTE B ON A.SupervisorEID = B.EID
    )
    
    INSERT INTO @tb
    select EID,NameCN,SupervisorEID,Layer from CTE where (@Layer IS NULL OR Layer=@Layer)
    
    return
    END
    
    GO

    例子二

    --[员工]表含成层级关系
    CREATE TABLE Employees (
        empid INT NOT NULL,
        mgrid INT NULL,--管理者ID字段,用于链接empid
        empname VARCHAR (25) NOT NULL,
        salary money NOT NULL,
        CONSTRAINT PK_Employees PRIMARY KEY (empid),
    )
    GO
    
    -- 插入实例数据,允许员工的管理者ID字段为null, 
    INSERT INTO Employees VALUES(1, NULL, 'Nancy', $10000.00)
    INSERT INTO Employees VALUES(2, 1, 'Andrew', $5000.00)
    INSERT INTO Employees VALUES(3, 1, 'Janet', $5000.00)
    INSERT INTO Employees VALUES(4, 1, 'Margaret',$5000.00) 
    INSERT INTO Employees VALUES(5, 2, 'Steven', $2500.00)
    INSERT INTO Employees VALUES(6, 2, 'Michael', $2500.00)
    INSERT INTO Employees VALUES(7, 3, 'Robert', $2500.00)
    INSERT INTO Employees VALUES(8, 3, 'Laura', $2500.00)
    INSERT INTO Employees VALUES(9, 3, 'Ann', $2500.00)
    INSERT INTO Employees VALUES(10, 4, 'Ina', $2500.00)
    INSERT INTO Employees VALUES(11, 7, 'David', $2000.00)
    INSERT INTO Employees VALUES(12, 7, 'Ron', $2000.00)
    INSERT INTO Employees VALUES(13, 7, 'Dan', $2000.00)
    INSERT INTO Employees VALUES(14, 11, 'James', $1500.00)
    GO
    
    --Create Departments table and insert demo values
    CREATE TABLE Departments (
        deptid INT NOT NULL PRIMARY KEY,
        deptname VARCHAR (25) NOT NULL,
        deptmgrid INT NULL REFERENCES Employees --部门管理者ID,外键参考Employees的empid字段
    )
    GO
    
    INSERT INTO Departments VALUES (1, 'HR', 2) 
    INSERT INTO Departments VALUES (2, 'Marketing', 7) 
    INSERT INTO Departments VALUES (3, 'Finance', 8) 
    INSERT INTO Departments VALUES (4, 'R&D', 9) 
    INSERT INTO Departments VALUES (5, 'Training', 4) 
    INSERT INTO Departments VALUES (6, 'Gardening', NULL)
    GO
    -- 这个自定义函数根据用工ID,返回他所有的下属(包括下属的下属,即所有层)
    CREATE FUNCTION dbo.fn_getsubtree(@empid AS INT) RETURNS @TREE TABLE
    (
      empid   INT NOT NULL,
      empname VARCHAR(25) NOT NULL,
      mgrid   INT NULL,
      lvl     INT NOT NULL
    )
    AS
    BEGIN
      WITH Employees_Subtree(empid, empname, mgrid, lvl) AS  --lvl层级字段
      ( 
        -- Anchor Member (AM)
        SELECT empid, empname, mgrid, 0
        FROM employees
        WHERE empid = @empid  --这个查询输出将作为下个查询的输入!
            -- 下属,即那些管理者字段的值等于自己的Employee字段
        UNION all
        -- Recursive Member (RM)
        SELECT e.empid, e.empname, e.mgrid, es.lvl+1
        FROM employees AS e
        JOIN employees_subtree AS es --employees_subtree是WITH后面的变量名,相当于JOIN自己链接自己
        ON e.mgrid = es.empid
      )
      INSERT INTO @TREE
      SELECT * FROM Employees_Subtree
      RETURN
    END
    GO
    
    -- Call for show
    SELECT * FROM fn_getsubtree(1)
    
    --通过这个例子理解CROSS APPLY 说明:表Departments和自定义函数fn_getsubtree链接
    --查询每个部门管理者他们包含(所有层次)的下属,特别说明,返回的结果集的记录存在部分记录字段重复
    --因为fn_getsubtree是返回所有层次的下属,所以下面的查询也返回每个部门下所有层次的下属
    SELECT *
    FROM Departments AS D
    CROSS APPLY fn_getsubtree(D.deptmgrid) AS ST --deptmgrid 部门的领导id

    例子三

    WITH T AS
    (
     SELECT empid, empname, mgrid,0 AS Lv FROM Employees
     UNION ALL
     SELECT e.empid, e.empname, e.mgrid,es.Lv+1 FROM Employees AS e --不支持*号!字段名必须一一写出来,并且和上面的SELECT一模一样!
     JOIN T AS es  --链接自己啊
     ON e.mgrid = es.empid
    )
    SELECT * FROM T
     
    已经在好多场合看到这些的写法了,所有觉得比较重要.
    ===========================
    用例数表
    CREATE TABLE Employees (
     empid INT NOT NULL,
     mgrid INT NULL,--管理者字段,是自链接字段!
     empname VARCHAR (25) NOT NULL,
     salary money NOT NULL,
     CONSTRAINT PK_Employees PRIMARY KEY (empid),
    )
    GO
     
    -- 允许员工的部门为null, 
    INSERT INTO Employees VALUES(1, NULL, 'Nancy', $10000.00)
    INSERT INTO Employees VALUES(2, 1, 'Andrew', $5000.00)
    INSERT INTO Employees VALUES(3, 1, 'Janet', $5000.00)
    INSERT INTO Employees VALUES(4, 1, 'Margaret',$5000.00) 
    INSERT INTO Employees VALUES(5, 2, 'Steven', $2500.00)
    INSERT INTO Employees VALUES(6, 2, 'Michael', $2500.00)
    INSERT INTO Employees VALUES(7, 3, 'Robert', $2500.00)
    INSERT INTO Employees VALUES(8, 3, 'Laura', $2500.00)
    INSERT INTO Employees VALUES(9, 3, 'Ann', $2500.00)
    INSERT INTO Employees VALUES(10, 4, 'Ina', $2500.00)
    INSERT INTO Employees VALUES(11, 7, 'David', $2000.00)
    INSERT INTO Employees VALUES(12, 7, 'Ron', $2000.00)
    INSERT INTO Employees VALUES(13, 7, 'Dan', $2000.00)
    INSERT INTO Employees VALUES(14, 11, 'James', $1500.00)
    GO
    =========================
  • 相关阅读:
    asp.net(c#)网页跳转七种方法小结
    asp.net用Zxing库实现条形码输出的具体实现
    SQL中 patindex函数的用法
    escape()、encodeURI()、encodeURIComponent()区别详解
    sql语句分页代码
    memcache安装
    LVS和Haproxy机器必须注意的几个参数
    Redis 三主三从集群搭建
    mogodb安装步骤及注意事项
    系统故障等级和故障报告规定
  • 原文地址:https://www.cnblogs.com/zhuji/p/9261604.html
Copyright © 2011-2022 走看看