当前位置:  开发笔记 > 编程语言 > 正文

当我们进行交叉申请时以及在SQL Server 2012中进行内部联接时

如何解决《当我们进行交叉申请时以及在SQLServer2012中进行内部联接时》经验,为你挑选了1个好方法。

我对SQL Server有一个小问题.我们何时使用cross apply,何时使用inner join?为什么cross apply在SQL Server中使用?

我有emp,dept表; 基于这两个表的,我写的inner joincross apply查询这样的:

----using cross apply
SELECT * 
FROM Department D 
CROSS APPLY 
    (SELECT * 
     FROM Employee E 
     WHERE E.DepartmentID = D.DepartmentID) A 

----using inner join 
SELECT * 
FROM Department D 
INNER JOIN Employee E ON D.DepartmentID = E.DepartmentID 

两个查询都返回相同的结果.

这里为什么cross apply需要SQL Server?有性能差异吗?你能告诉我吗?

我们cross apply何时使用何时使用inner join?这些查询之间的任何性能差异?请告诉我在SQL Server中编写此查询的最佳方法是什么.



1> Shnugo..:

INNER JOINCROSS APPLY(同与LEFT JOINOUTER APPLY)的关系非常密切.在您的示例中,我假设引擎将找到相同的执行计划.

A JOIN是条件下两组之间的链接

a APPLY逐行子调用

但是 - 如上所述 - 优化器非常智能,并且 - 至少在如此简单的情况下 - 理解,它会归结为相同.

JOIN会尽量收集子集,并将其链接在特定的条件

APPLY会尝试打电话与当前行的值的相关结果,一遍又一遍.

差异在于使用XML方法和更复杂的场景调用表值函数(应该是内联的 -syntax!).nodes().

一个例子可以APPLY用来模拟变量

...使用行式计算的结果,就像使用变量一样:

DECLARE @dummy TABLE(ID INT IDENTITY, SomeString VARCHAR(100));
INSERT INTO @dummy VALUES('Want to split/this at the two/slashes.'),('And/this/also');

SELECT d.ID
      ,d.SomeString
      ,pos1
      ,pos2
      ,LEFT(d.SomeString,pos1-1)
      ,SUBSTRING(d.SomeString,pos1+1,pos2-pos1-1)
      ,SUBSTRING(d.SomeString,pos2+1,1000)
FROM @dummy AS d
CROSS APPLY(SELECT CHARINDEX('/',d.SomeString) AS pos1) AS x
CROSS APPLY(SELECT CHARINDEX('/',d.SomeString,x.pos1+1) AS pos2) AS y

这与以下相同,但更容易阅读(和键入):

SELECT d.ID
      ,d.SomeString
      ,LEFT(d.SomeString,CHARINDEX('/',d.SomeString)-1)
      ,SUBSTRING(d.SomeString,CHARINDEX('/',d.SomeString)+1,CHARINDEX('/',d.SomeString,(CHARINDEX('/',d.SomeString)+1))-(CHARINDEX('/',d.SomeString)+1))
      ,SUBSTRING(d.SomeString,CHARINDEX('/',d.SomeString,(CHARINDEX('/',d.SomeString)+1))+1,1000)
FROM @dummy AS d

XML方法的一个例子 .nodes()

DECLARE @dummy TABLE(SomeXML XML)
INSERT INTO @dummy VALUES
(N'
  a1
  a2
  a3
  Here is b!
');

SELECT All_a_nodes.value(N'.',N'nvarchar(max)')
FROM @dummy
CROSS APPLY SomeXML.nodes(N'/root/a') AS A(All_a_nodes);

结果

a1
a2
a3

内联函数调用的一个示例

CREATE FUNCTION dbo.TestProduceRows(@i INT)
RETURNS TABLE
AS
RETURN
    SELECT TOP(@i) ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) AS Nr FROM master..spt_values
GO

CREATE TABLE dbo.TestData(ID INT IDENTITY, SomeString VARCHAR(100),Number INT);
INSERT INTO dbo.TestData VALUES
 ('Show me once',1)
,('Show me twice',2)
,('Me five times!',5);

SELECT *
FROM TestData
CROSS APPLY dbo.TestProduceRows(Number) AS x;

GO
DROP TABLE dbo.TestData;
DROP FUNCTION dbo.TestProduceRows;

结果

1   Show me once    1   1
2   Show me twice   2   1
2   Show me twice   2   2
3   Me five times!  5   1
3   Me five times!  5   2
3   Me five times!  5   3
3   Me five times!  5   4
3   Me five times!  5   5

推荐阅读
路人甲
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有