2012-10-23 18 views
10

Eventuali duplicati:
Referring to a Column Alias in a WHERE ClauseCome utilizzo la clausola alias in where?

SELECT 
Trade.TradeId, 
Isnull(Securities.SecurityType,'Other') SecurityType, 
TableName, 
CASE 
WHEN 
SecurityTrade.SecurityId IS NOT NULL 
THEN 
SecurityTrade.SecurityId 
ELSE 
Trade.SecurityId 
END AS PricingSecurityID, 
sum(Trade.Quantity)OVER(Partition by Securities.SecurityType, SecurityTrade.SecurityId,Trade.Price, Buy,Long) as sumQuantity, 
--added porfolio id for Getsumofqantity 
Trade.PortfolioId, 

Trade.Price, 
case 
when (Buy = 1 and Long = 1) then 1 
when (Buy = 0 and Long = 0) then 1 
else 0 
end Position 
from 
Fireball_Reporting..Trade 

where porfolioid =5 and Position =1 

voglio usare Posizione = 1 nel mio clausola where, che è un alias del caso

case 
when (Buy = 1 and Long = 1) then 1 
when (Buy = 0 and Long = 0) then 1 
else 0 
end Position 

COME POSSO usarlo in dove clausola?

ho provato direttamente utilizzare questa dichiarazione CASE in cui la clausola, ma non è riuscito ti prego, aiutami

WHERE Trade.SecurityId = @SecurityId AND PortfolioId = @GHPortfolioID AND 
       (case when (Buy = 1 and Long = 1) then 1 when (Buy = 0 and Long = 0) then 1 else 0 end Position = 1) 
+0

Non è possibile se non si aggiunge un'altra selezione e si verifica postion = 1 sulla query esterna. –

+0

Quale linguaggio SQL stai usando? – StingyJack

+0

T SQL in sql server 2008 – Neo

risposta

31

standard SQL non consente riferimenti a alias di colonna in una clausola WHERE. Questa restrizione è imposta perché quando viene valutata la clausola WHERE, il valore della colonna potrebbe non essere stato ancora determinato.

Taken from MySQL Doc

column_alias possono essere utilizzati in una clausola ORDER BY, ma non possono essere utilizzati in una WHERE, GROUP BY o HAVING.

Taken from the MSSQL Doc

+3

'Preso da MySQL Doc' su una risposta contrassegnata come' sql-server'? – MatBailie

13

Non è possibile, non direttamente.

Se si avvolge l'intera query in una sottoquery, tuttavia, funziona correttamente.

SELECT 
    * 
FROM 
(
    SELECT 
    Trade.TradeId, 
    Isnull(Securities.SecurityType,'Other') SecurityType, 
    TableName, 
    CASE 
     WHEN SecurityTrade.SecurityId IS NOT NULL THEN SecurityTrade.SecurityId 
               ELSE Trade.SecurityId 
    END AS PricingSecurityID, 
    sum(Trade.Quantity)OVER(Partition by Securities.SecurityType, 
    SecurityTrade.SecurityId,Trade.Price, Buy,Long) as sumQuantity, 
    --added porfolio id for Getsumofqantity 
    Trade.PortfolioId, 
    Trade.Price, 
    case 
     when (Buy = 1 and Long = 1) then 1 
     when (Buy = 0 and Long = 0) then 1 
            else 0 
    end Position 
    from 
    Fireball_Reporting..Trade 
    where 
    porfolioid = 5 
) 
    AS data 
WHERE 
    Position = 1 

Questo significa che non è necessario ripetere la dichiarazione CASE in WHERE clausola. (Manutenibile e SECCO).

E 'anche una struttura che consente l'ottimizzatore di comportarsi come se si avuto semplicemente te stesso ripetuto nella clausola WHERE.

È anche molto portatile per altri RDBMS.


In SQL Server, allora hai anche un'altra opzione ...

SELECT 
    Trade.TradeId, 
    Isnull(Securities.SecurityType,'Other') SecurityType, 
    TableName, 
    CASE 
    WHEN SecurityTrade.SecurityId IS NOT NULL THEN SecurityTrade.SecurityId 
               ELSE Trade.SecurityId 
    END AS PricingSecurityID, 
    sum(Trade.Quantity)OVER(Partition by Securities.SecurityType, 
    SecurityTrade.SecurityId,Trade.Price, Buy,Long) as sumQuantity, 
    --added porfolio id for Getsumofqantity 
    Trade.PortfolioId, 
    Trade.Price, 
    position.val AS Position 
from 
    Fireball_Reporting..Trade 
CROSS APPLY 
(
    SELECT 
    case 
     when (Buy = 1 and Long = 1) then 1 
     when (Buy = 0 and Long = 0) then 1 
            else 0 
    end AS val 
) 
    AS position 
where 
    porfolioid = 5 
    AND position.val = 1 
+0

La risposta di Juergen e la tua risposta si riferiscono al fatto che "..quando la clausola WHERE viene valutata, il valore della colonna potrebbe non essere stato ancora determinato". ma dal momento che stai usando la query secondaria che sarebbe stata. – Mukus

5

Non si può fare direttamente questo ... ma si può avvolgere un ulteriore selezionare giro tutto e utilizzare la clausola dove:

select * from 
    ( SELECT 
    Trade.TradeId, 
    Isnull(Securities.SecurityType,'Other') SecurityType, 
    TableName, 
    CASE 
    WHEN 
    SecurityTrade.SecurityId IS NOT NULL 
    THEN 
    SecurityTrade.SecurityId 
    ELSE 
    Trade.SecurityId 
    END AS PricingSecurityID, 
    sum(Trade.Quantity)OVER(Partition by Securities.SecurityType,  SecurityTrade.SecurityId,Trade.Price, Buy,Long) as sumQuantity, 
    --added porfolio id for Getsumofqantity 
    Trade.PortfolioId, 
    Trade.Price, 
    case 
    when (Buy = 1 and Long = 1) then 1 
    when (Buy = 0 and Long = 0) then 1 
    else 0 
    end Position 
    from 
    Fireball_Reporting..Trade 
    where porfolioid =5 and Position =1 
    )x 
    where x.position = 1 
0

sono probabilmente manca qualcosa ma sicuramente questo sarà coprirlo:

WHERE (Buy = 1 and Long = 1) OR (Buy = 0 and Long = 0)

+1

Lo fa. Ma "Do not Repeat Yourself" (DRY) è un principio di base che aiuta enormemente la manutenzione e il debug *. Quindi, essere in grado di fare riferimento a un calcolo molte volte è altamente desiderabile. – MatBailie