2012-10-23 4 views
10

可能性の重複:
Referring to a Column Alias in a WHERE Clausewhere句でエイリアスを使用するにはどうすればよいですか?

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 

私はどのようにすることができます例エイリアス

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

である私のwhere句内の位置= 1を使用したいですwhere句で使用しますか?

私は私を助けてください

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

外部クエリに別のselectとcheck postion = 1を追加しない限り、できません。 –

+0

どのようなSQL言語を使用していますか? – StingyJack

+0

T SQL in sql server 2008 – Neo

答えて

31

標準SQL を直接where句でそのCASE文を使用してみましたが、 を失敗したがWHERE句でカラムのエイリアスへの参照を禁止します。この制限は、WHERE句が評価されるときに列の値がまだ決定されていない可能性があるために課せられます。

Taken from MySQL Doc

column_aliasは、ORDER BY句で使用することができ、それをWHERE、GROUP BY、または句を有することを使用することができません。

Taken from the MSSQL Doc

+3

'' sql-server'とタグ付けされた答えに '' MySQL Docから取った? – MatBailie

13

あなたが直接ではなく、することはできません。

ただし、サブクエリでクエリ全体をラップすると、正常に動作します。

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 

これは、あなたがWHERE句でCASEステートメントを繰り返す必要がないことを意味します。 (維持可能でDRY)。

また、オプティマイザは、あなたは単にWHERE句の中で自分自身を繰り返していたかのように動作することを可能にする構造です。

他のRDBMSにも移植性があります。 SQL Serverでの


、その後、あなたはまた、別のオプションを持っている...

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

Juergenの答えとあなたの答えは、 "WHERE句が評価されたときに、列の値がまだ決定されていない可能性があります。しかし、あなたがされているサブクエリを使用しているので。 – Mukus

5

あなたが直接これを行うことはできません...しかし、あなたはそれをすべての周りに追加の選択をラップすることができますし、私はおそらく何かが欠けていますが、確かに、これはそれをカバーします

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

where句を使用します

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

+1

です。しかし、 "自分自身を繰り返さないでください"(DRY)は、メンテナンスやデバッグに大いに役立ちます。したがって、1回の計算を何度も参照できることが非常に望ましい。 – MatBailie