交叉应用范围不可见?

时间:2015-02-25 08:58:04

标签: sql-server cross-apply

目前我有一个udf,返回table。它返回3行。每行返回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) )

请注意多种用法:

enter image description here

确定。所以我被告知要使用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

  • 它无法识别EXISTS子句中的myCrossApply:

enter image description here

我该如何解决这个问题?

问题#2

  • 此外,由于交叉申请
  • ,行已被删除

例如(让我们删除未知的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

enter image description here

我该如何解决这个问题?

我只是不希望每次重新计算UDF,所以他们建议使用交叉申请。

1 个答案:

答案 0 :(得分:1)

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

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

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