7月10日 使用 APPLY MSDN

转载 2015年07月10日 09:03:25


使用 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 值。

相关文章推荐

7月10日 使用CTE MSDN

 WITH common_table_expression (Transact-SQL) SQL Server 2014 其他版本 SQL Server...

2017年7月10日听课笔记Java应用软件开发

一. Application:存活时间最长,可以多用户共享,在服务器端 Session:每一个浏览器对应服务器只有一个session,比如当我们在学校官网,通过教务系统进行成绩的查...

2015年7月10日 UITableView 2

UITableView UITableViewCell  的性能优化 原来的代码   这样的话 每当视图 中出现一条table 就会重新创建一个cell  会造成资源的浪费 - (UIT...

2016年7月10日版卡表文件

  • 2016-11-21 11:10
  • 321KB
  • 下载

MSDN 杂志 07年7月号

  • 2007-08-18 08:03
  • 2.05MB
  • 下载

2017年3月10日,周结(三),开源框架初使用

2017年3月10日,周结(三),开源框架初体会.

记录您的代码使用 XML 注释---转自MSDN

记录您的代码使用 XML注释    查找文档您的代码的简单而有效的方法? XML注释提供很好的解决方案。在 Visual Studio 2005中最先引入 Visual Basic的 XML ...

VC++ MSDN中的 _beginthreadex与_endthreadex 的使用例子

1._beginthread, _beginthreadex . 用于创建线程 uintptr_t _beginthread( void( *start_address )( void *...

Win7操作系统下安装VC++6.0、MSDN并使用MFC绘图

2015年开学了,在群里各位老师的鼎力支持下,我的计算机图形学基础教程已经出版了十二五国家级规划教材。由于库存的原因,可能有的老师已经拿到了带标志的教材,也可能有的老师的教材上没有十二五标志。比如我这...

MSDN:使用泛型 类型“System.Collections.Generic.IComparer <T> ”需要“1”个类型参数”。

今天在学习实现点击listview(视图为Details) 的Column时进行自动排序,查询MSDN给出了一个要自定义ICompare接口的实例;结果实例运行时是抛出错误错误 “ 使用泛型 类型“S...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)