根据别名列名进行过滤

时间:2010-02-22 14:58:31

标签: sql sql-server sql-server-2005 alias where-clause

我正在使用SqlServer 2005,我有一个我命名的列。

查询类似于:

SELECT id, CASE WHEN <snip extensive column definition> END AS myAlias
FROM myTable
WHERE myAlias IS NOT NULL

然而,这给了我错误:

  

“无效的列名'myAlias'。”

有没有办法解决这个问题?在过去,我已经在WHERE或HAVING部分中包含了列定义,但那些大部分都是简单的,IE COUNT(*)或其他。我可以在这个ad-hoc查询中包含整个列定义,但如果由于某种原因我需要在生产查询中执行此操作,我宁愿只使用一次列定义,因此我不必更新两者(和忘了在某个时候做一个)

5 个答案:

答案 0 :(得分:14)

你不能在where子句中引用别名......你要么必须在WHERE中复制CASE,要么你可以使用这样的子查询:

SELECT id, myAlias
FROM
(
    SELECT id, CASE WHEN <snip extensive column definition> END AS myAlias
    FROM myTable
) data
WHERE myAlias IS NOT NULL

答案 1 :(得分:5)

使用CTE也是一种选择:

;with cte (id, myAlias)
 as (select id, case when <snip extensive column definition> end as myAlias 
      from myTable)
 select id, myAlias
  from cte
  where myAlias is not null

答案 2 :(得分:2)

CASE子句中添加相同的WHERE语句:

SELECT id, CASE WHEN <snip extensive column definition> END AS myAlias
FROM myTable
WHERE CASE WHEN <snip extensive column definition> END IS NOT NULL

修改

另一种选择是嵌套查询:

SELECT id, myAlias
FROM (
    SELECT id, CASE WHEN <snip extensive column definition> END AS myAlias
    FROM myTable
) AS subTable
WHERE myAlias IS NOT NULL

(编辑:已移除HAVING选项,因为这不正确(感谢@ OMG Ponies))

答案 3 :(得分:1)

把案子放在哪里。 SQL Server将足够智能,只需对其进行一次评估,因此您不会真正复制代码:

SELECT id, CASE WHEN <snip extensive column definition> END AS myAlias
FROM myTable
WHERE CASE WHEN <snip extensive column definition> END IS NOT NULL

你可以将它包装在派生表中:

SELECT dt.id, dt.myAlias
    FROM (
          SELECT id, CASE WHEN <snip extensive column definition> END AS myAlias
          FROM myTable
         ) dt
    WHERE dt.myAlias IS NOT NULL

但是,我尝试避免在没有限制性WHERE的情况下派生表。您可以尝试查看它是否会影响性能。

答案 4 :(得分:0)

我最终创建了一个临时表来执行此操作。这里有一些伪代码可以给你一个想法。这适用于复杂的连接,我只是在这里展示一个简单的案例。

--Check to see if the temp table already exists
If(OBJECT_ID('tempdb..#TempTable') Is Not Null)
Begin
    DROP TABLE #TempTable
End

--Create the temp table
CREATE TABLE #TempTable
{
     YourValues NVARCHAR(100)
}

--Insert your data into the temp table        
INSERT INTO #TempTable(YourValues)
SELECT yt.Column1 as YourColumnOne FROM YourTable yt

--Query the filtered data based on the aliased column    
SELECT * 
FROM #TempTable
WHERE YourColumnOne = 'DataToFilterOn'

--Don't forget to remove the temp table
DROP TABLE #TempTable