zoukankan      html  css  js  c++  java
  • 使用 APPLY

     原文地址:http://technet.microsoft.com/zh-cn/library/ms175156(v=SQL.105).aspx 

    使用 APPLY 运算符可以为实现查询操作的外部表表达式返回的每个行调用表值函数。表值函数作为右输入,外部表表达式作为左输入。通过对右输入求值来获得左输入每一行的计算结果,生成的行被组合起来作为最终输出。APPLY 运算符生成的列的列表是左输入中的列集,后跟右输入返回的列的列表。

    注意注意

    若要使用 APPLY,数据库兼容级别必须至少为 90。

    APPLY 有两种形式:CROSS APPLY 和 OUTER APPLY。CROSS APPLY 仅返回外部表中通过表值函数生成结果集的行。OUTER APPLY 既返回生成结果集的行,也返回不生成结果集的行,其中表值函数生成的列中的值为 NULL。

    例如,考虑下列表 EmployeesDepartments

     
    复制
    --Create Employees table and insert values.
    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
    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 values.
    CREATE TABLE Departments
    (
        deptid    INT NOT NULL PRIMARY KEY
        ,deptname  VARCHAR(25) NOT NULL
        ,deptmgrid INT NULL REFERENCES Employees
    );
    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);
    

    Departments 表中的多数部门都具有一个经理 ID,这些 ID 与 Employees 表中的雇员相对应。以下表值函数接受雇员 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
      ( 
        -- Anchor Member (AM)
        SELECT empid, empname, mgrid, 0
        FROM Employees
        WHERE empid = @empid
    
        UNION all
        
        -- Recursive Member (RM)
        SELECT e.empid, e.empname, e.mgrid, es.lvl+1
        FROM Employees AS e
          JOIN Employees_Subtree AS es
            ON e.mgrid = es.empid
      )
      INSERT INTO @TREE
        SELECT * FROM Employees_Subtree;
    
      RETURN
    END
    GO
    

    若要返回每个部门经理的各级下属,请使用以下查询。

     
    复制
    SELECT D.deptid, D.deptname, D.deptmgrid
        ,ST.empid, ST.empname, ST.mgrid
    FROM Departments AS D
        CROSS APPLY fn_getsubtree(D.deptmgrid) AS ST;
    

    下面是结果集:

     
    复制
    deptid      deptname   deptmgrid   empid       empname    mgrid       lvl
    ----------- ---------- ----------- ----------- ---------- ----------- ---
    1           HR         2           2           Andrew     1           0
    1           HR         2           5           Steven     2           1
    1           HR         2           6           Michael    2           1
    2           Marketing  7           7           Robert     3           0
    2           Marketing  7           11          David      7           1
    2           Marketing  7           12          Ron        7           1
    2           Marketing  7           13          Dan        7           1
    2           Marketing  7           14          James      11          2
    3           Finance    8           8           Laura      3           0
    4           R&D        9           9           Ann        3           0
    5           Training   4           4           Margaret   1           0
    5           Training   4           10          Ina        4           1
    

    注意,Departments 表中每一行复制的次数与针对部门经理执行 fn_getsubtree 而返回的行数相同。

    另外,结果中不显示 Gardening 部门。因为该部门没有经理,所以 fn_getsubtree 将针对该部门返回空集。通过使用 OUTER APPLYGardening 部门也将在结果集中显示,其 deptmgrid 字段以及由 fn_getsubtree 返回的字段中的值都为 Null 值。

  • 相关阅读:
    安全模式下卸载windows installer打包的软件(转)
    OAF页面集成条形码或者二维码
    记一次客户生产环境供应商门户服务器无法访问
    QML显示圆形图片
    QML加载gif
    QML之信号与槽
    QML访问C++类内部
    QML使用C++对象
    C++条件变量
    C/C++程序所占用内存区域
  • 原文地址:https://www.cnblogs.com/niaowo/p/3622973.html
Copyright © 2011-2022 走看看