在连接中使用表值函数

Posted

技术标签:

【中文标题】在连接中使用表值函数【英文标题】:Using Table valued Function in join 【发布时间】:2012-10-11 18:37:06 【问题描述】:

有一个表值函数,它提供多行作为输出,有 2 列作为输出。

现在我想在查询employees表中的所有员工时使用这个函数

我正在使用 CROSS APPLY,但它需要很长时间并且没有给出任何结果。

这是我尝试过的查询

select *
from emp A Cross APPLY fnempDiv(A.EmpID)

【问题讨论】:

emp 表中有多少行?从select * from fnempDiv([some EmpID]) 返回了多少行? 你必须给我们大概的数量,或者尝试使用 nolock 来检查是否有其他交易被阻塞 @Kumar 如果它被阻塞,它仍然会在阻塞清除后完成并返回行 @james 在 15000 左右有很多行 @kumar 桌子上没有锁 【参考方案1】:

我正在使用交叉应用

需要很长时间

不幸的是,这就是 CROSS APPLY 的本质,因为它是逐行运算符。它适用于一些员工行(方便),但根据您的描述,您应该避免在此查询中使用它,并将 APPLY 中的查询扩展到外部查询。一个简单的 INNER JOIN 就可以了。

没有给出任何结果。

CROSS APPLY 删除不会从 APPLY 生成任何行的 emp A 记录。 OUTER APPLY 将保留emp A 记录。如果您总共获得 0 条记录,则您可能传递了错误的列,例如A.EmpID 不是正确的密钥。

如果函数是这样定义的(来自您的评论):

CREATE FUNCTION dbo.fnempDiv(@EmpID)
RETURNS TABLE AS RETURN
 SELECT A.EmpID,D.Name
 FROM empdetail A
 INNER JOIN empdiv D on A.empID=D.ID
 where EXISTS (select * from X)
GO

这完全没有意义。 Select * from X 要么使整个查询失败,要么成为一个无效条件,只需在 X 中记录或以其他方式。输入参数@EmpID也没有被使用。

另一方面,如果声明如下:

CREATE FUNCTION dbo.fnempDiv(@EmpID)
RETURNS TABLE AS RETURN
 SELECT A.EmpID,D.Name
 FROM empdetail A
 INNER JOIN empdiv D on A.empID=D.ID
 where A.EmpID = @EmpID
GO

然后你的完整查询可以重写

select E.*, A.emp_ID as EmpDetail_Emp_ID, D.Name
from emp E
INNER JOIN empdetail A ON E.emp_ID=A.EMP_ID
INNER JOIN empdiv D on A.empID=D.ID

此外,连接 A.empID=D.ID 甚至看起来都不正确。

【讨论】:

你能告诉我如何在内部连接的帮助下做到这一点。 SELECT A.EmpID,D.Name FROM empdetail A INNER JOIN empdiv D on A.empID=D.ID where EXISTS (select * from X) X 表在这里做什么?你真的有一张叫X的桌子吗?

以上是关于在连接中使用表值函数的主要内容,如果未能解决你的问题,请参考以下文章

连接使用表值函数创建的表时优化 TSQL

Entity Framework 的 FromSql 方法执行使用内部连接选择语句的 SQL Server 表值函数

sql server表值函数和视图如何一起使用

查看 vs 表值函数 vs 子查询

在 Laravel Eloquent 中连接表值

如何在实体框架代码优先方法中使用表值函数?