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

Sql 在where子句中如何使用别名?,sql,sql-server,qtsql,Sql,Sql Server,Qtsql,可能重复: 我想在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 我如何在where子句中使用它 我试图在where子句中直接使用CASE语句,但失败了 WHERE Trade.SecurityId = @SecurityId AND PortfolioId = @GHPortfolioID

可能重复:

我想在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
我如何在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)
报告说:

列别名可以在ORDER BY子句中使用,但不能在WHERE、GROUP BY或HAVING子句中使用

类似的说法是:

标准SQL不允许在WHERE子句中引用列别名。施加此限制是因为在计算WHERE子句时,可能尚未确定列值


在MySQL中,你至少可以

你不能,不能直接

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

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
语句。(可维护且干燥)

它也是一种结构,允许乐观主义者表现得就像你在
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

您不能直接执行此操作…但您可以在其周围附加一个select并使用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和Long=1)或(Buy=0和Long=0)

除非在外部查询中添加另一个select and check position=1,否则不能执行此操作。您使用的是什么SQL语言?SQL server 2008中的SQL是这样做的。但是“不要重复你自己”(DRY)是一个基本原则,它极大地帮助维护和调试。因此,能够多次引用一个计算结果是非常可取的。Juergen的答案和您的答案都与以下事实有关:“.当计算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