在where子句中不能使用临时列?

Mic*_*l A 6 sql t-sql sql-server sql-server-2005 sql-server-2008

select  cast(de.ApprovalOrder AS VARCHAR(32)) 
            + cast(de.EntityCode AS VARCHAR(32)) 
            + isnull(cast(de.DelegationCode AS VARCHAR(32)), '') as 'RowID' ,
            *
from    workflow.delegation_engine de
where   RowID <> NULL
Run Code Online (Sandbox Code Playgroud)

当我尝试执行以下操作时收到错误:

消息207,级别16,状态1,行13无效的列名称'RowID'.

只是想知道我如何引用这个临时列?我搜索了以前的帖子,建议使用'have'来实现这一点,但这似乎也不起作用.

Lie*_*ers 9

一种解决方案是对整个语句进行子选择,在结果上应用where子句

select  *
from    (
          select  cast(de.ApprovalOrder AS VARCHAR(32)) 
                  + cast(de.EntityCode AS VARCHAR(32)) 
                  + isnull(cast(de.DelegationCode AS VARCHAR(32)), '') as 'RowID'
                  , *
          from    workflow.delegation_engine de
        ) de 
where   de.RowID IS NOT NULL
Run Code Online (Sandbox Code Playgroud)

另一种解决方案可能是重复WHERE子句中的整个子句

select  cast(de.ApprovalOrder AS VARCHAR(32)) 
        + cast(de.EntityCode AS VARCHAR(32)) 
        + isnull(cast(de.DelegationCode AS VARCHAR(32)), '') as 'RowID' ,
        *
from    workflow.delegation_engine de
where   cast(de.ApprovalOrder AS VARCHAR(32)) 
        + cast(de.EntityCode AS VARCHAR(32)) 
        + isnull(cast(de.DelegationCode AS VARCHAR(32)), '') IS NOT NULL
Run Code Online (Sandbox Code Playgroud)

或者您可以测试每个单独的字段为NULL

select  cast(de.ApprovalOrder AS VARCHAR(32)) 
        + cast(de.EntityCode AS VARCHAR(32)) 
        + isnull(cast(de.DelegationCode AS VARCHAR(32)), '') as 'RowID' ,
        *
from    workflow.delegation_engine de
where   de.ApprovalOrder IS NOT NULL
        AND de.EntityCode IS NOT NULL
Run Code Online (Sandbox Code Playgroud)

  • +1作为Option3是Option2的一个更实用的重构,对于优化器而言通常比Option1更有用.*[它可能感觉不那么优雅,但是当它为优化者提供更多线索来减少执行计划时,就会有腿,我喜欢腿.)* (3认同)
  • @Codingo - 所以我们进入了性能与维护的世界.让我们跳舞吧! (2认同)

小智 5

您要么必须使用WHERE子句中的express ,要么将SELECT查询用作子查询,如下所示:

select *
from
(
    select  cast(de.ApprovalOrder AS VARCHAR(32))  
                + cast(de.EntityCode AS VARCHAR(32))  
                + isnull(cast(de.DelegationCode AS VARCHAR(32)), '') as RowID, 
                * 
    from    workflow.delegation_engine de 
)
where RowID is not NULL 
Run Code Online (Sandbox Code Playgroud)

或者,更粗略的(在我看来)路线将是:

select  cast(de.ApprovalOrder AS VARCHAR(32))    
            + cast(de.EntityCode AS VARCHAR(32))    
            + isnull(cast(de.DelegationCode AS VARCHAR(32)), '') as RowID,   
            *   
from    workflow.delegation_engine de   
where   cast(de.ApprovalOrder AS VARCHAR(32))    
            + cast(de.EntityCode AS VARCHAR(32))    
            + isnull(cast(de.DelegationCode AS VARCHAR(32)), '') is not null  
Run Code Online (Sandbox Code Playgroud)

我每次都会选择第一个解决方案.

还要注意我已经改变了你的WHERE条款

RowID <> NULL
Run Code Online (Sandbox Code Playgroud)

RowID is not NULL
Run Code Online (Sandbox Code Playgroud)

这是因为<> NULL永远不会评估为真.SQL Server NULL使用IS和测试(即未知)IS NOT.