2010-02-22 88 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