当前位置: 首页 > 编程笔记 >

SQL 交叉应用和外部应用基础

颜阳炎
2023-03-14
本文向大家介绍SQL 交叉应用和外部应用基础,包括了SQL 交叉应用和外部应用基础的使用技巧和注意事项,需要的朋友参考一下

示例

在正确的表达式中使用表值函数时,将使用Apply。

创建一个Department表来保存有关部门的信息。然后创建一个Employee表,其中包含有关雇员的信息。请注意,每个员工都属于一个部门,因此Employee表与Department表具有参照完整性。

第一个查询从Department表中选择数据,并使用CROSS APPLY评估Department表的每个记录的Employee表。第二个查询只是将Department表与Employee表连接在一起,并生成所有匹配的记录。

SELECT *
FROM Department D
CROSS APPLY (
    SELECT *
    FROM Employee E
    WHEREE.DepartmentID= D.DepartmentID
) A
GO
SELECT *
FROM Department D
INNER JOIN Employee E
  OND.DepartmentID= E.DepartmentID

如果您查看它们产生的结果,则它是完全相同的结果集。它与JOIN有何不同以及如何帮助编写更有效的查询。

脚本2中的第一个查询从Department表中选择数据,并使用OUTER APPLY为Department表的每个记录评估Employee表。对于那些在Employee表中不匹配的行,这些行包含NULL值,如在第5行和第6行的情况下所见。第二个查询仅在Department表和Employee表之间使用LEFT OUTER JOIN。如预期的那样,查询返回Department表中的所有行;即使对于那些在Employee表中不匹配的行。

SELECT *
FROM Department D
OUTER APPLY (
    SELECT *
    FROM Employee E
    WHEREE.DepartmentID= D.DepartmentID
) A
GO
SELECT *
FROM Department D
LEFT OUTER JOIN Employee E
  OND.DepartmentID= E.DepartmentID
GO

即使以上两个查询返回相同的信息,执行计划也会有所不同。但是在成本方面不会有太大的区别。

现在是时候查看一下真正需要APPLY运算符的位置了。在脚本#3中,我正在创建一个表值函数,该函数接受DepartmentID作为其参数,并返回属于该部门的所有员工。下一个查询从Department表中选择数据,并使用CROSS APPLY与我们创建的函数联接。它从外部表表达式(在我们的示例中为Department表)传递每一行的DepartmentID,并为每一行评估函数,类似于相关的子查询。下一个查询使用OUTER APPLY代替CROSS APPLY,因此不同于CROSS APPLY仅返回相关数据的情况,OUTER APPLY也返回不相关的数据,将NULL放入丢失的列中。

CREATE FUNCTIONdbo.fn_GetAllEmployeeOfADepartment(@DeptID AS int)
RETURNS TABLE
AS
  RETURN
  (
  SELECT
    *
  FROM Employee E
  WHEREE.DepartmentID= @DeptID
  )
GO
SELECT
  *
FROM Department D
CROSS APPLY dbo.fn_GetAllEmployeeOfADepartment(D.DepartmentID)
GO
SELECT
  *
FROM Department D
OUTER APPLY dbo.fn_GetAllEmployeeOfADepartment(D.DepartmentID)
GO

因此,现在如果您想知道,我们可以使用简单的联接代替上面的查询吗?那么答案是否定的,如果将上述查询中的CROSS / OUTER APPLY替换为INNER JOIN / LEFT OUTER JOIN,指定ON子句(约为1 = 1)并运行查询,您将获得“多部分标识符” D.DepartmentID”无法绑定。” 错误。这是因为使用JOIN时,外部查询的执行上下文不同于函数(或派生表)的执行上下文,并且您不能将外部查询的值/变量作为参数绑定到函数。因此,此类查询需要APPLY运算符。

 类似资料:
  • 问题内容: 我想为Entity Framework查询创建一些测试用例,这些查询用例肯定会生成包含CROSS APPLY或OUTER APPLY运算符的SQL命令。 有人可以显示出现这类SQL查询的典型情况吗? 问题答案: 在LINQ 2 SQL中,这总是导致: 在EF中,这可能会失败,也可能会导致(我不知道是哪一个)。这是一个 关联联接,在SQL端需要一个。

  • 问题内容: 我需要在MySQL(EC2 RDS MySQL实例)中使用CROSS APPLY。看起来MySQL无法识别CROSS APPLY语法。有谁可以帮助我吗? 这是查询。 问题答案: 最接近的 直接 逼近是将相关子查询作为谓词的联接。 但是,根据您的情况,您只需要目标表中的一个字段。这意味着您可以直接在SELECT语句中使用相关子查询。

  • 问题内容: 我当时使用CROSS APPLY来连接Users和GeoPhone表,并且一切工作都很快,但是现在我在Phone列中有具有NULL值的Users。交叉应用会在最终输出中跳过这些行。所以我切换到OUTER APPLY。但是它的工作速度非常慢(当输出的总行数仅增加1000时,速度要慢15倍以上)。 相对: 我想了解原因。如我所见,执行计划是不同的。但是从理论上讲,我看不到任何可能导致这种速

  • 问题内容: 给定开始日期和结束日期,我需要计算这两个日期之间的实例数。因此,给出以下内容: 桌子: 如果我在第一个(01/01)和第二个(02/01)之间看,我希望计数为2。如果我在寻找第3个到第4个,则期望计数为3。在整个日期范围内,那么我希望计数为4。有意义吗? 注意: 日期已转换为午夜,无需为此添加任何代码。此外,在整个问题中,日期均为dd / MM / yyyy格式。 目前,我有类似以下内

  • 问题内容: 使用CROSS APPLY的主要目的是什么? 我已经读过(模糊地通过Internet上的帖子),cross apply如果您要进行分区,则在选择大型数据集时可能会更有效率。(想起分页) 我也知道,CROSS APPLY不需要UDF作为右表。 在大多数INNER JOIN查询(一对多关系)中,我可以将它们重写为use CROSS APPLY,但它们始终会为我提供等效的执行计划。 任何人都

  • HDP-2.5.0.0,使用Ambari 2.4.0.1 配置单元表ReportSetting如下: 列'SerializedReportSetting'在源SQL Server db中是一种XML数据类型,但在Sqoop导入期间被转换为String,这是它在SQL Server中的外观: 在配置单元表中: 在SQL Server上正常工作的查询: 从ReportSetting限制1中选择xpat