34

重複の可能性:
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   

ケースのエイリアスであるwhere句でPosition=1を使用したい

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

where句でどのように使用できますか?

where句でそのCASEステートメントを直接使用してzoを試しましたが、失敗しました。

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

4 に答える 4

70

SQL サーバーのドキュメントには次のように書かれています。

column_alias は ORDER BY 句で使用できますが、WHERE、GROUP BY、または HAVING 句では使用できません

MySQL docと同様に、次のように述べています。

標準 SQL では、WHERE 句で列の別名を参照することはできません。この制限が課されるのは、WHERE 句が評価されるときに、列の値がまだ決定されていない可能性があるためです。

MySQLでは、少なくともSELECTでエイリアスを再利用できます

于 2012-10-23T13:03:37.427 に答える
40

直接ではありません。

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

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   

これは、句CASE内でステートメントを繰り返す必要がないことを意味します。WHERE(保守可能で 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
于 2012-10-23T13:06:09.643 に答える
8

これを直接行うことはできません...しかし、追加の選択をすべてラップして、where句を使用できます。

    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
于 2012-10-23T13:09:53.640 に答える
0

私はおそらく何かが欠けていますが、確かにこれはそれをカバーします:

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

于 2012-10-23T13:46:34.887 に答える