使用where子句会导致无效的列名错误

时间:2015-09-04 15:42:30

标签: sql sql-server sql-server-2012

我正在使用SQL Server 2012。

我写下面的查询除了包含最后一行'NomDiff<> 0' 。

它告诉我NomDiff是一个无效的列名。我不明白为什么也不知道如何让查询只返回nomDiff不等于零的行?

;with pf as
(
    select Name, Sedol, Nominal from tblTempPLF 
    where FundCode = 'CSGE'
), pc as
(
    select Name, Sedol, Nominal from tblTempPCF 
    where FundCode = 'BTCM'
)
select coalesce(pf.Name, pc.Name) Name, coalesce(pf.Sedol, pc.Sedol) Sedol, 
isnull(pf.Nominal,0) PfNom, isnull(pc.Nominal,0) PcNom, isnull(pf.Nominal,0) - isnull(pc.Nominal,0) NomDiff
from pf full outer join pc on pf.Sedol = pc.Sedol
where NomDiff <> 0 

5 个答案:

答案 0 :(得分:5)

使用APPLY VALUES是一种不必使用子查询或其他CTE的好方法:

WITH    pf
AS ( SELECT
      Name ,
      Sedol ,
      Nominal
      FROM tblTempPLF
      WHERE FundCode = 'CSGE'
    ),
pc
AS ( SELECT
      Name ,
      Sedol ,
      Nominal
      FROM tblTempPCF
      WHERE FundCode = 'BTCM'
    )
  SELECT
      Name = COALESCE(pf.Name, pc.Name),
      Sedol = COALESCE(pf.Sedol, pc.Sedol),
      PfNom = ISNULL(pf.Nominal, 0),
      PcNom = ISNULL(pc.Nominal, 0),
      NomDiff = Nom.Diff
  FROM pf
  FULL OUTER JOIN pc
  ON  pf.Sedol = pc.Sedol
  CROSS APPLY(VALUES(ISNULL(pf.Nominal, 0) - ISNULL(pc.Nominal, 0))) AS Nom(Diff)
  WHERE Nom.Diff <> 0;

答案 1 :(得分:3)

您无法在alias子句中使用先前定义的where。改为使用计算。

select coalesce(pf.Name, pc.Name) Name, 
coalesce(pf.Sedol, pc.Sedol) Sedol,   
isnull(pf.Nominal,0) PfNom, isnull(pc.Nominal,0) PcNom, 
isnull(pf.Nominal,0) - isnull(pc.Nominal,0) NomDiff
from pf full outer join pc on pf.Sedol = pc.Sedol
where isnull(pf.Nominal,0) - isnull(pc.Nominal,0)<> 0

答案 2 :(得分:2)

您无法在WHERE中使用该列的别名,因为您要在SELECT中创建该列,请更改为:

WHERE isnull(pf.Nominal,0) - isnull(pc.Nominal,0) <> 0

或者您可以使用子查询/ cte使别名可用于引用它的外部查询。

原因是WHERE实际上是在SELECT之前评估的,优化器会在担心要返回哪些字段之前过滤掉行。

答案 3 :(得分:1)

只需添加另一个cte即可使用别名

;with pf as
(
    select Name, Sedol, Nominal from tblTempPLF 
    where FundCode = 'CSGE'
), pc as
(
    select Name, Sedol, Nominal from tblTempPCF 
    where FundCode = 'BTCM'
), anotherOne as /* add another cte */
(
    select 
        coalesce(pf.Name, pc.Name) Name, 
        coalesce(pf.Sedol, pc.Sedol) Sedol, 
        isnull(pf.Nominal,0) PfNom, 
        isnull(pc.Nominal,0) PcNom, 
        isnull(pf.Nominal,0) - isnull(pc.Nominal,0) NomDiff
    from pf full 
    outer join pc 
        on pf.Sedol = pc.Sedol
)
select *
from anotherOne
where NomDiff <> 0 

答案 4 :(得分:1)

由于您已经在使用CTE,因此将外部查询作为另一个CTE包装,然后过滤掉NomDiff(计算列的别名)会更容易。 Alias不在同一个select语句中,因此为了直接使用Alias,您需要将其包含在subqueryCTE中。否则,你也可以直接在where子句中使用计算,就像其他人在这里建议的那样。

;WITH pf
AS (
    SELECT NAME
        ,Sedol
        ,Nominal
    FROM tblTempPLF
    WHERE FundCode = 'CSGE'
    )
    ,pc
AS (
    SELECT NAME
        ,Sedol
        ,Nominal
    FROM tblTempPCF
    WHERE FundCode = 'BTCM'
    )
    ,calc
AS (
    SELECT coalesce(pf.NAME, pc.NAME) NAME
        ,coalesce(pf.Sedol, pc.Sedol) Sedol
        ,isnull(pf.Nominal, 0) PfNom
        ,isnull(pc.Nominal, 0) PcNom
        ,isnull(pf.Nominal, 0) - isnull(pc.Nominal, 0) NomDiff
    FROM pf
    FULL OUTER JOIN pc ON pf.Sedol = pc.Sedol
    )
SELECT *
FROM calc
WHERE NomDiff <> 0