Sql 在 where 子句中抛出聚合错误
Sql throwing up error on aggregate in where clause
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
这是抛出错误:无效的列名'observed'
为什么?
您不能在同一范围内的 where
子句中重复使用 select
子句中定义的别名。
此处的解决方法是横向连接:
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
您不能在 WHERE
中通过别名引用列,因为 SELECT
在 WHERE
之后解析。参见 Logical Processing Order of the SELECT statement。
将子查询移动到 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;
如果子查询可能没有 return 任何行,则使用 OUTER APPLY
代替。
正如其他关于逻辑查询处理的回答中提到的,WHERE 子句对新的派生列不可见。
Read more on Logical query processing
- FROM
- ON
- JOIN
- WHERE
- GROUP BY
- WITH CUBE/ROLLUP
- HAVING
- SELECT
- DISTINCT
- ORDER BY
- TOP
- OFFSET/FETCH
如果要引用专栏,可以有多种方式。下面给出了一些方法:
方式 1:利用 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
方式二:使用派生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
我相信您在 SQL Server 2008 中有常见的 table 表达式,那么为什么不简单地将现有查询包装在 WITH 中以便您的别名可用?:
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
除非我遗漏了什么?
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
这是抛出错误:无效的列名'observed' 为什么?
您不能在同一范围内的 where
子句中重复使用 select
子句中定义的别名。
此处的解决方法是横向连接:
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
您不能在 WHERE
中通过别名引用列,因为 SELECT
在 WHERE
之后解析。参见 Logical Processing Order of the SELECT statement。
将子查询移动到 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;
如果子查询可能没有 return 任何行,则使用 OUTER APPLY
代替。
正如其他关于逻辑查询处理的回答中提到的,WHERE 子句对新的派生列不可见。
Read more on Logical query processing
- FROM
- ON
- JOIN
- WHERE
- GROUP BY
- WITH CUBE/ROLLUP
- HAVING
- SELECT
- DISTINCT
- ORDER BY
- TOP
- OFFSET/FETCH
如果要引用专栏,可以有多种方式。下面给出了一些方法:
方式 1:利用 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
方式二:使用派生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
我相信您在 SQL Server 2008 中有常见的 table 表达式,那么为什么不简单地将现有查询包装在 WITH 中以便您的别名可用?:
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
除非我遗漏了什么?