可能性のある複製:
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
caseのエイリアスである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ステートメントを直接使用しようとしましたが、失敗してください
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)
標準SQL WHERE句の列エイリアスへの参照を禁止。 WHERE句が評価されるとき、列の値がまだ決定されていない可能性があるため、この制限が課せられます。
column_aliasはORDER BY句で使用できますが、WHERE、GROUP BY、またはHAVING句では使用できません。
直接ではなく、できません。
ただし、クエリ全体をサブクエリでラップすると、正常に機能します。
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
ステートメントを繰り返す必要はありません。 (維持可能および乾燥)。
また、オプティマイザーがif as you hadを単純に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
これを直接行うことはできません...しかし、すべてを追加の選択でラップし、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
私はおそらく何かを見逃していますが、確かにこれはそれをカバーします:
WHERE (Buy = 1 and Long = 1) OR (Buy = 0 and Long = 0)