18

我正在使用 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(*) 或其他。我可以在这个临时查询中包含整个列定义,但是如果由于某种原因我需要在生产查询中执行此操作,我希望只使用一次列定义,这样我就不必同时更新两者(并且在某个时候忘记做一个)

4

5 回答 5

16

您不能在这样的 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
于 2010-02-22T15:02:15.933 回答
6

使用 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
于 2010-02-22T15:14:15.313 回答
4

在子句中放入相同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))

于 2010-02-22T15:01:50.183 回答
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 的派生表。你可以试试看它是否影响性能。

于 2010-02-22T15:00:12.830 回答
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
于 2018-02-16T18:23:09.270 回答