交叉申请声明的问题和来自

Issue with the cross apply statement and from

我正在尝试做点什么,但我遇到了一个问题。问题是我需要创建一个存储过程,如果该过程的参数是实际日期或更早的日期,则查询中的 2 个参数和 where 的一部分将被忽略。我最初使用 if else 来忽略这些情况,但代码重复且维护不一致。所以我需要做同样的事情但没有 if /else 语句。如有任何帮助,我们将不胜感激。

select 
                Cats.*,
                Zone.[D] as [De], -- this part would be avoided if @Min and @Max are null
                Zone.[R] as [Re]  -- this part would be avoided if @Min and @Max are null
            from 
                flv
                CROSS APPLY  --all the cross apply would be avoided if @Min and @Max are null
                    (
                        select
                            x
                        from 
                            XXXX
                        where 
                            XXXX.IDx= 1
                    ) as Data
where           
                    ---where clause

我只想避免在 2 个参数为空的情况下交叉应用

XXXX.IDx= 1 更改为 @Min IS NOT NULL AND @Max IS NOT NULL AND XXXX.IDx= 1 并且您的交叉应用不会受到任何伤害。但是,这意味着不会从 CROSS APPLY 以及整个查询中返回任何行。所以你还需要 CROSS APPLY 变成 OUTER APPLY

例如以下脚本:

DECLARE @test INT
SELECT * FROM dbo.tmpTable AS TT
    OUTER APPLY (
        SELECT * FROM dbo.test AS T
        WHERE @test IS NOT NULL
    ) AS T

给出如下执行计划,特别注意这里的Filter组件。

当您将鼠标悬停在过滤器组件上时,您可能会注意到以下内容

意思是 dbo.test 在这种情况下,只有在满足启动谓词的情况下才会被扫描。将 OPTION (RECOMPILE) 放在查询上并查看实际的查询计划,如果 @test 为空,table 甚至不在查询计划中。