0

我有以下查询,我想在Percentage包含聚合的表达式上使用 where 子句:

SELECT Percentage = CONVERT(DECIMAL(10,1),100 - COUNT(some_irrelevant_column))
FROM Product P INNER JOIN Item PD
ON PD.ProductId = P.ProductId
WHERE Percentage < 50;

这会产生以下错误:

列名“百分比”无效。

4

4 回答 4

5

您可以使用公用表表达式

with cte as (
    select CONVERT(DECIMAL(10,1),100 - (CAST(COUNT(DISTINCT case when PD.ExceptionCode  != ' ' then PD.Id  END) as float)/CAST(COUNT(PD.Id) as float)*100)) as Percentage
from Product as P
    inner join Item as PD on PD.ProductId = P.ProductId
)
select Percentage from cte where Percentage < 50

可以使用subquery,但对我来说 CTE 更具可读性

select *
from (
    select CONVERT(DECIMAL(10,1),100 - (CAST(COUNT(DISTINCT case when PD.ExceptionCode  != ' ' then PD.Id  END) as float)/CAST(COUNT(PD.Id) as float)*100)) as Percentage
from Product as P
    inner join Item as PD on PD.ProductId = P.ProductId
) as A
where A.Percentage < 50

也可以使用 have 来解决这个问题但它的可读性或可维护性不强:

select CONVERT(DECIMAL(10,1),100 - (CAST(COUNT(DISTINCT case when PD.ExceptionCode != ' ' then PD.Id  END) as float)/CAST(COUNT(PD.Id) as float)*100)) as Percentage
from Product as P
    inner join Item as PD on PD.ProductId = P.ProductId
having CONVERT(DECIMAL(10,1),100 - (CAST(COUNT(DISTINCT case when PD.ExceptionCode != ' ' then PD.Id  END) as float)/CAST(COUNT(PD.Id) as float)*100)) < 50
于 2013-08-14T17:22:39.947 回答
4

问题是WHEREandHAVING子句都在列表之前被解析。SELECT这与聚合无关。如果您有一个非常简单的表达式,也会发生同样的事情,例如:

SELECT a = 1 + 2 WHERE a = 3;

想象一下 SQL Server 实际上是反向读取的:“对于 a = 3 的行,返回表达式 1 + 2,并将其标记为 a。” 这不起作用,因为 a 尚不存在,以便检查 a = 3。我稍微谈谈为什么这是这个答案以及dba.stackexchange.com 上的这个答案(那里还有一些其他答案也值得一读)。

因此,您不能在SELECT列表中创建别名,然后在其他子句中引用别名(ORDER BY这是唯一可行的,即使在那里您也会发现异常)。解决方法是使用子查询或 CTE:

SELECT a FROM (SELECT 1 + 2) AS x(a) WHERE a = 3;

;WITH x(a) AS (SELECT 1 + 2) SELECT a FROM x WHERE a = 3;

或者重复表达式(通常是不可取的):

SELECT a = 1 + 2 WHERE 1 + 2 = 3;
于 2013-08-14T18:27:32.650 回答
2

要基于聚合函数过滤结果集,您需要将其包含在HAVING子句中,而不是WHERE子句中。

于 2013-08-14T17:22:29.113 回答
0

聚合可能不会出现在 WHERE 子句中,除非它位于 HAVING 子句或选择列表中包含的子查询中,并且被聚合的列是外部引用

于 2013-08-14T17:33:23.677 回答