我正在使用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查询中包含整个列定义,但如果由于某种原因我需要在生产查询中执行此操作,我宁愿只使用一次列定义,因此我不必更新两者(和忘了在某个时候做一个)
答案 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