2010-02-22 6 views
9

Ich benutze SqlServer 2005 und ich habe eine Spalte, die ich benannt habe.Filter basierend auf einem Alias-Spaltennamen

Die Abfrage ist so etwas wie:

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

aber das gibt mir den Fehler:

"Invalid column name 'myAlias'."

Gibt es eine Möglichkeit, dies zu umgehen? In der Vergangenheit habe ich die Spaltendefinition entweder in die WHERE- oder die HAVING-Sektion aufgenommen, aber diese waren meistens einfach, IE COUNT (*) oder was auch immer. Ich kann die gesamte Spaltendefinition in diese Ad-hoc-Abfrage einschließen, aber wenn ich aus irgendeinem Grund dies in einer Produktionsabfrage tun müsste, würde ich die Spaltendefinition lieber nur einmal haben, also muss ich beide nicht aktualisieren (und Vergiss es irgendwann einmal)

Antwort

11

Sie können keine Aliase in einer where-Klausel wie die Referenz ... Sie haben entweder den Fall, in dem WHERE zu duplizieren, oder Sie eine Unterabfrage wie diese verwenden:

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

Ach, ich hoffte, es wäre einfacher. –

+0

Ich auch, es sollte eigentlich eine allgemeinere Lösung sein –

1

den Fall in die wo. SQL Server intelligent genug sein wird, um es nur einmal zu bewerten, so dass Sie nicht wirklich den Code zu duplizieren:

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

Sie es in einer abgeleiteten Tabelle wickeln könnte:

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 

aber ich versuche, Vermeiden Sie abgeleitete Tabellen ohne restriktives WHERE. Sie können es versuchen, um zu sehen, ob es sich auf die Leistung auswirkt oder nicht.

+0

@KM, meine Sorge war mehr über mich aktualisieren einen Fall und vergessen, den zweiten zu aktualisieren. Wie Sie erwarte ich, dass SQL Server den zweiten Anruf optimieren wird –

1

Setzen Sie die gleiche CASE Anweisung in der WHERE Klausel:

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

EDIT

Eine weitere Option zum Nest ist die Abfrage:

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

(Edit: entfernt HAVING Option, da dies falsch war (danke @OMG Ponies))

+0

Sie sind ganz richtig - ich werde diesen Teil löschen. – Codesleuth

+0

@OMG Ponys: versuchen Sie es in SQL Server. ohne Gruppe von, es ist das gleiche wie WHERE so ziemlich ... http://msdn.microsoft.com/en-us/library/ms180199%28SQL.90%29.aspx So könnte Codesleuths Lösung ohne Verwendung von abgeleitet korrekt gewesen sein Tabelle – gbn

+0

@gbn: Seltsam! Werde es definitiv versuchen, wenn ich zur Arbeit komme. Entschuldigung, Codesleuth. –

5

Mit CTEs ist auch eine Option:

;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

Dank Philip, ich bin nicht vertraut mit CTE's, es sieht aus, als ob es eine temporäre Ansicht ist. Wäre das eine faire Aussage? –

+0

@nathan koop: ja, wie die abgeleiteten Tischlösungen auch angeboten ... – gbn

+0

Danke, ich werde einen Blick darauf werfen –

0

Ich habe am Ende eine temporäre Tabelle erstellt, um dies zu tun. Hier ist ein Pseudo-Code, um Ihnen eine Idee zu geben. Dies funktionierte mit einer komplexen Verbindung, ich zeige hier nur einen einfachen Fall.

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