2010-02-22 80 views
9

我正在使用SqlServer 2005,并且我有一个我命名的列。基于别名列名进行筛选

查询是这样的:

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

然而,这给我的错误:

"Invalid column name 'myAlias'."

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

回答

11

不能引用别名一个地方像子句中......您可能已复制的情况下,在WHERE,或者您也可以使用这样的子查询:

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

唉,我希望它会更简单。 – 2010-02-22 16:12:23

+0

我也是,实际上应该有更通用的解决方案 – 2013-05-08 12:49:58

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。你可以试试看它是否会影响性能。

+0

@KM,我的担心更多的是关于更新一个CASE并忘记更新第二个。和你一样,我期望SQL Server能够优化第二个调用 – 2010-02-22 15:37:27

1

把同样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))

+0

你是非常正确的 - 我会删除那部分。 – Codesleuth 2010-02-22 15:07:36

+0

@OMG小马:在SQL Server中试用它。没有组合,它与WHERE相同... http://msdn.microsoft.com/en-us/library/ms180199%28SQL.90%29.aspx因此,Codesleuth的解决方案可能是正确的,无需使用派生表 – gbn 2010-02-22 15:39:39

+0

@gbn:奇怪!当我开始工作时肯定会尝试。对不起,Codesleuth。 – 2010-02-22 15:48:14

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 
+0

谢谢菲利普,我不熟悉CTE,看起来好像是一种临时视图。这是一个公平的声明? – 2010-02-22 15:40:13

+0

@nathan koop:​​是的,和派生的表格解决方案一样... – gbn 2010-02-22 15:52:57

+0

谢谢我会仔细研究一下 – 2010-02-22 16:19:39

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