Reputation: 6668
I am using SQL Server 2012.
I have written the query below which works fine apart from when I include the last line 'where NomDiff <> 0'.
It tells me NomDiff is an invalid column name. I don't understand why and don't know how to get the query to return only rows where the nomDiff is not equal to zero?
;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
Upvotes: 1
Views: 955
Reputation: 976
Using APPLY VALUES
is a good way of not having to use a subquery, or another 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;
Upvotes: 5
Reputation: 13713
Since you are already using CTE
, it would be easier to just wrap that outer query as another CTE
and then filter out the NomDiff
(alias for the calculated column). Alias
does not scope within the same select statement, so in order to use an Alias
directly, you would need to wrap that either in a subquery
or a CTE
. Otherwise, you could also directly use the calculation in the where clause like others have suggested here.
;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
Upvotes: 1
Reputation: 48177
Just add another cte so you can use the alias
;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
Upvotes: 1
Reputation: 34774
You can't use the alias for the column in the WHERE
since you are creating it in the SELECT
, change to:
WHERE isnull(pf.Nominal,0) - isnull(pc.Nominal,0) <> 0
Or you can use a subquery/cte to make the alias available to an outer query that references it.
The reason for this is that WHERE
is actually evaluated prior to SELECT
, the optimizer filters out rows before worrying about which fields to return.
Upvotes: 2
Reputation: 49260
You can't use a previously defined alias
in the where
clause. Use the calculation instead.
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
Upvotes: 3