交叉应用范围不可见?

Cross apply scope is not visible?

目前我有一个 udf,其中 return 是一个 table。它 returns 3 行。每行 return parameter's value *10

类似于(伪):

ALTER FUNCTION [dbo].[myUdf]
(   
    @num int
)
RETURNS  @myTable TABLE (h int )     

AS
begin
    insert into @myTable 
    SELECT h=@num * 10 UNION
    SELECT h=@num * 20 UNION
    SELECT h=@num * 30
    return @myTable
end

好的。

现在,在我的代码中我做了类似的事情:

select  .... , 
has20 = CASE WHEN EXISTS (SELECT 1 FROM  dbo.myUdf(A.ID) WHERE h=20) 
             THEN 0 ELSE 1 end
,
has30 = CASE WHEN EXISTS (SELECT 1 FROM  dbo.myUdf(A.ID) WHERE h=30)
             THEN 0 ELSE 1 end
...
from A join B...on ...
Where x .. or ..y ... or Exists (select 1 from dbo.myUdf(A.ID) )

请注意多种用法:

好的。所以我被告知要使用 Cross apply,所以我做了:

让我们举一个简单的例子:

我有这 3 行数据:

DECLARE @t TABLE(myNum INT)
INSERT @t
VALUES  (1), (2), (3)

所以让我们使用交叉应用:

SELECT  has20  = CASE WHEN  EXISTS( SELECT h FROM myCrossApply WHERE mynum=20 ) 
             THEN '1' ELSE '0' END   , 
        has30  = CASE WHEN  EXISTS( SELECT h FROM myCrossApply WHERE mynum=30 ) 
             THEN '1' ELSE '0' END  
FROM   @t tmp
       CROSS APPLY (
         -- notice  ! in reality there is a udf Table here , I jsut made a simple conversion insted so you can test it.
         SELECT h = tmp.myNum * 10 UNION SELECT h = tmp.myNum * 20 UNION SELECT h = tmp.myNum * 30
        ) myCrossApply

但是这里有 2 个错误,我不知道如何解决:

问题 #1

我该如何解决这个问题?

问题 #2

例如(让我们删除 unknown exists 子句以显示第二个问题):

SELECT  dummy =  tmp.myNum , myCrossApply.h
         /*...*/ 

FROM   @t tmp
       CROSS APPLY (
         SELECT h = tmp.myNum * 10 UNION SELECT h = tmp.myNum * 20 UNION SELECT h = tmp.myNum * 30
        ) myCrossApply

我该如何解决这个问题?

我只是不想每次都重新计算UDF,所以他们建议使用cross apply。

myCrossApply 不是真正的 table,它是对数据子集别名的引用。 您也不能将 tmp 称为 table。

以下代码应使用与脚本相同的逻辑:

declare @t table(mynum int)
insert @t values(1),(2),(3)

SELECT  has20  = myCrossApply.chk1, 
        has30  = myCrossApply.chk2,
        mynum
FROM   @t tmp
CROSS APPLY (
SELECT 
  max(case when h = 20 then 1 else 0 end) chk1, 
  max(case when h = 30 then 1 else 0 end) chk2
FROM
(   SELECT h = tmp.myNum * 10
    UNION all
    SELECT h = tmp.myNum * 20 
    UNION all
    SELECT h = tmp.myNum * 30) x
) myCrossApply

结果:

has20   has30   mynum
1       1       1
1       0       2
0       1       3