2012-10-23 10 views
10

Mögliche Duplizieren:
Referring to a Column Alias in a WHERE ClauseWie benutze ich Alias ​​in where-Klausel?

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 

ich will Position verwenden = 1 in meiner where-Klausel, die ein Alias ​​von Fall ist

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

Wie kann ich Verwenden Sie es in Where-Klausel?

versuchte ich, dass die CASE-Anweisung in Klausel direkt wo gescheitert, aber helfen bitte

mir
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

Sie können nicht, es sei denn, Sie fügen eine weitere Auswahl hinzu und überprüfen Position = 1 auf äußere Abfrage. –

+0

Welche SQL-Sprache verwenden Sie? – StingyJack

+0

T SQL im SQL-Server 2008 – Neo

Antwort

31

Standard-SQL Verweise auf Spaltenaliasnamen in einer WHERE-Klausel nicht zulässt. Diese Einschränkung wird auferlegt, da bei der Auswertung der WHERE-Klausel der Spaltenwert möglicherweise noch nicht ermittelt wurde.

Taken from MySQL Doc

spaltenalias kann in einer ORDER BY-Klausel verwendet werden, aber es kann nicht in einer WHERE, GROUP BY-Klausel oder HAVING verwendet werden.

Taken from the MSSQL Doc

+3

'Aus MySQL Doc' auf eine Antwort mit dem Tag' sql-server' genommen? – MatBailie

13

Sie können nicht, nicht direkt.

Wenn Sie jedoch die gesamte Abfrage in eine Unterabfrage einfügen, funktioniert sie problemlos.

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 

Dies bedeutet, dass Sie nicht über die CASE Anweisung in WHERE Klausel wiederholen müssen. (Wartbar und trocken).

Es ist auch eine Struktur, die die optimiser als ob Sie hatte einfach selbst in der Klausel WHERE wiederholt verhalten können.

Es ist auch sehr portabel zu anderen RDBMS.


In SQL Server, dann haben Sie auch eine andere Option ...

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

Juergens Antwort und Ihre Antwort bezieht sich auf die Tatsache, dass "..wenn WHERE-Klausel ausgewertet wird, der Spaltenwert möglicherweise noch nicht bestimmt wurde." aber da Sie Sub-Abfrage verwenden, die gewesen sein wird. – Mukus

5

Sie können dies nicht direkt tun ... aber Sie können eine zusätzliche wickeln wählen um sie alle und verwenden sie die where-Klausel:

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

ich wahrscheinlich etwas fehlt bin aber sicher das wird es decken:

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

+1

Es tut. Aber "Do not Repeat Yourself" (DRY) ist ein Grundprinzip, das die Wartung und das Debugging enorm unterstützt *. Es ist daher sehr wünschenswert, eine Berechnung mehrmals referenzieren zu können. – MatBailie