SELECT A.A1, A.B2, A.C2,
(select AVG(X1.parm)
from (VALUES (A.KK1),(A.KK2)) as X1(parm)
where X1.parm >110 and X1.parm is not NULL
) as observed
FROM Table A
WHERE observed > 200
This is throwing up error: Invalid column name 'observed' why?
You can't reuse an alias defined in the select
clause in the where
clause in the same scope.
A workaround here is a lateral join:
select a.a1, a.b2, a.c2, x.observed
from table a
cross apply (
select avg(x.parm) observed
from (values (a.kk1),(a.kk2)) as x(parm)
where x.parm > 110 and x.parm is not null
) x
where x.observed > 200
You can't reference a column by its alias in the WHERE
, as the SELECT
is parsed after the WHERE
. See Logical Processing Order of the SELECT statement .
Move the subquery into the FROM
:
SELECT A.A1,
A.B2,
A.C2,
C.observed
FROM [Table] A
CROSS APPLY (SELECT AVG(X1.parm) AS observed
FROM (VALUES (A.KK1),
(A.KK2)) X1 (parm)
WHERE X1.parm > 110
AND X1.parm IS NOT NULL) C
WHERE C.observed > 200;
If the subquery might not return any rows, then use an OUTER APPLY
instead.
As mentioned in other answer about logical query processing, the WHERE clause does not have visbibility to the new derived column.
Read more on Logical query processing
- FROM
- ON
- JOIN
- WHERE
- GROUP BY
- WITH CUBE/ROLLUP
- HAVING
- SELECT
- DISTINCT
- ORDER BY
- TOP
- OFFSET/FETCH
If you want to refer to the column, then you can do in multiple ways. Some approaches are given below:
Way 1: Leverage CTE
;WITH CTE_Table1 AS
(
SELECT A.A1, A.B2, A.C2,
(select AVG(X1.parm)
from (VALUES (A.KK1),(A.KK2)) as X1(parm)
where X1.parm >110 and X1.parm is not NULL
) as observed
FROM Table A
)
SELECT * FROM cte_Table1
WHERE observed > 200
Way 2: Using derived table
SELECT * FROM
(SELECT A.A1, A.B2, A.C2,
(select AVG(X1.parm)
from (VALUES (A.KK1),(A.KK2)) as X1(parm)
where X1.parm >110 and X1.parm is not NULL
) as observed
FROM Table A) as derived_Table1
WHERE observed > 200
I believe you have common table expressions with SQL Server 2008, so why not simply wrap your existing query in a WITH so that your alias becomes available?:
WITH cte AS (
SELECT A.A1, A.B2, A.C2,
(select AVG(X1.parm)
from (VALUES (A.KK1),(A.KK2)) as X1(parm)
where X1.parm >110 and X1.parm is not NULL
) as observed
FROM Table A
)
SELECT * FROM cte
WHERE observed > 200
Unless there's something I'm missing?
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.