我如何在where子句中使用别名?

Neo*_*Neo 17 sql sql-server qtsql

可能重复:
引用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   
Run Code Online (Sandbox Code Playgroud)

我想在我的where子句中使用Position = 1,这是case的别名

case
when (Buy = 1 and Long = 1) then 1
when (Buy = 0 and Long = 0) then 1
else 0
end Position
Run Code Online (Sandbox Code Playgroud)

我如何在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)
Run Code Online (Sandbox Code Playgroud)

jue*_*n d 43

标准SQL 不允许在WHERE子句中引用列别名.强制执行此限制是因为在评估WHERE子句时,可能尚未确定列值.

取自MySQL Doc

column_alias可以在ORDER BY子句中使用,但不能在WHERE,GROUP BY或HAVING子句中使用.

取自MSSQL Doc


Mat*_*lie 19

你不能,不能直接.

但是,如果将整个查询包装在子查询中,则可以正常工作.

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   
Run Code Online (Sandbox Code Playgroud)

这意味着您不需要重复CASE语句in WHERE子句.(可维护和干燥).

这也是一个结构,使优化器的行为,就好像已经简单地重复自己的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
Run Code Online (Sandbox Code Playgroud)

  • 子查询是一个绝妙的解决方案! (2认同)

Stu*_*044 5

你不能直接这样做......但是你可以用一个额外的周围所有的选择和使用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
Run Code Online (Sandbox Code Playgroud)