2013-04-23 7 views
29

quando ho cercato di eseguire il codice qui sotto in SQL Server 2005 sto ottenendo l'erroreCome utilizzare alias nome di colonna in cui la clausola in SQL Server

valido nome della colonna DistanceFromAddress

Codice:

select 
    SQRT(POWER(cast(Program_Latitude as float) - cast('41.5126237' as float), 2) + 
    POWER(cast(Program_Longitude as float) - cast('-81.6516411' as float), 2)) * 62.1371192 AS DistanceFromAddress 
from 
    tblProgram 
where 
    DistanceFromAddress < 2 

sto ottenendo i valori correttamente utilizzando l'istruzione sELECT, ma quando ho provato a verificare le condizioni where DistanceFromAddress < 2 sto ottenendo l'errore.

Come posso risolvere questo problema?

+0

Possibile duplicato di [riferimento a un alias di colonna in una clausola WHERE] (https://stackoverflow.com/questions/8370114/referring-to-a-column-alias-in-a-where-clause) – Vadzim

+0

I quess, basta duplicare l'espressione che la clausola 'WHERE' darebbe un piano migliore delle sottomissioni che sono proposte nelle risposte qui. – Vadzim

risposta

35

Non è possibile utilizzare le colonne alias in una clausola WHERE. Puoi provare a utilizzare una tabella derivata.Forse qualcosa di simile (mi dispiace, non testato):

SELECT * FROM 
(SELECT SQRT(POWER(cast(Program_Latitude as float) - cast('41.5126237' as float), 2) + 
POWER(cast(Program_Longitude as float) - cast('-81.6516411' as float), 2)) * 62.1371192 
AS DistanceFromAddress from tblProgram) mytable 
WHERE DistanceFromAddress < 2 
24

La clausola WHERE viene elaborato prima clausola SELECT (*), e quindi gli alias non sono disponibili. Spostarsi con un subquery o CTE - ecco una CTE:

; with Distances as (
    select SQRT(POWER(cast(Program_Latitude as float) - cast('41.5126237' as float), 2) + 
POWER(cast(Program_Longitude as float) - cast('-81.6516411' as float), 2)) * 62.1371192 
AS DistanceFromAddress 
    from tblProgram 
) 
select * from Distances where DistanceFromAddress < 2 

(*) - beh, i sistemi sono liberi di riordinare le operazioni come meglio credono, fino a quando il risultato è "come se "l'istruzione SQL è stata elaborata in un certo logical order. Naturalmente, quando tutto ciò che non va in SQL Server è dove è produces errors a causa di problemi di conversione nella clausola SELECT per righe/valori che dovrebbero essere eliminati dalla clausola WHERE.

1
select 
    SQRT(
    POWER(cast(Program_Latitude as float) - cast('41.5126237' as float), 2) + 
    POWER(cast(Program_Longitude as float) - cast('-81.6516411' as float), 2) 
) * 62.1371192 AS DistanceFromAddress 
from tblProgram 
having DistanceFromAddress < 2 

potrebbe funzionare (anche se non sembra, senza avere un gruppo dalla clausola pure).

Il problema è che è possibile utilizzare solo nomi nell'ambito della tabella o delle tabelle selezionate all'interno della clausola where. Where è un pre filtro che filtra le righe prima che siano selezionate, quindi espressioni come questa nella definizione del campo non sono ancora state eseguite e gli alias non sono disponibili.

La clausola Having funziona come post filtro dopo il raggruppamento e può utilizzare alias dalla query, anche se temo che sia necessario avere una clausola effettiva (non sicura).

L'alternativa è avere una sottoselezione (tabella derivata o selezionare in selezione), dove si selezionano prima le distanze per ciascuna riga, quindi selezionare solo le distanze rilevanti da tali risultati. Funzionerà:

select d.DistanceFromAddress 
from 
    (select 
    SQRT(
     POWER(cast(Program_Latitude as float) - cast('41.5126237' as float), 2) + 
     POWER(cast(Program_Longitude as float) - cast('-81.6516411' as float), 2) 
    ) * 62.1371192 AS DistanceFromAddress 
    from tblProgram) d 
where d.DistanceFromAddress < 2 

Oppure è possibile ripetere l'espressione. Ciò rende la tua query più difficile da mantenere, ma in alcuni casi potrebbe funzionare per te. Ad esempio se non vuoi restituire la distanza effettiva, ma solo, ad esempio, il nome del punto di interesse a quella distanza. In tal caso, è necessario avere l'espressione solo nella clausola where, nel qual caso l'argomento manutenibilità è scomparso e questa soluzione è un'alternativa perfetta.

select 
    tblProgram.POIname 
    /* Only if you need to return the actual value 
    , SQRT(
    POWER(cast(Program_Latitude as float) - cast('41.5126237' as float), 2) + 
    POWER(cast(Program_Longitude as float) - cast('-81.6516411' as float), 2) 
) * 62.1371192 AS DistanceFromAddress */ 
from tblProgram 
where 
    -- Use this if you only want to filter by the value. 
    SQRT(
    POWER(cast(Program_Latitude as float) - cast('41.5126237' as float), 2) + 
    POWER(cast(Program_Longitude as float) - cast('-81.6516411' as float), 2) 
) * 62.1371192 < 2 
0

Penso che si possa usare solo AS per visualizzare i valori finali. Per fare una comparazione, la selezione dovrebbe essere restituita da un'altra istruzione select al suo interno.

come:

SELECT a.disfromaddr FROM 
(SELECT SQRT(POWER(cast(Program_Latitude as float) - cast('41.5126237' as float), 2) + 
POWER(cast(Program_Longitude as float) - cast('-81.6516411' as float), 2)) * 62.1371192 
AS DistanceFromAddress FROM tblProgram) 
a WHERE a.disfromaddr < 2 

si può provare questo.

Problemi correlati