SQL - 聚合可能不会出现在 WHERE 子句中,除非它位于 HAVING 子句中包含的子查询中
Posted
技术标签:
【中文标题】SQL - 聚合可能不会出现在 WHERE 子句中,除非它位于 HAVING 子句中包含的子查询中【英文标题】:SQL - An aggregate may not appear in the WHERE clause unless it is in a subquery contained in a HAVING clause 【发布时间】:2021-04-05 17:06:00 【问题描述】:如果您看到下图,我只想查看平均收入高于总体平均水平的那些类别。
我正在使用的查询如下。最后一行导致了问题。
WITH cte_avg AS (
SELECT P.prod_cat, Avg_revenue = AVG(CAST(T.total_amt AS NUMERIC))
FROM [dbo].[Transactions] AS T
LEFT JOIN [dbo].[prod_cat_info] AS P ON T.prod_cat_code=P.prod_cat_code
GROUP BY P.prod_cat
)
SELECT prod_cat, Avg_revenue
FROM cte_avg
WHERE Avg_revenue > AVG(Avg_revenue)
我得到的错误是:
聚合可能不会出现在 WHERE 子句中,除非它出现在 HAVING 子句或选择列表中包含的子查询中,并且被聚合的列是外部引用。
请告诉我如何解决这个问题。谢谢!
【问题讨论】:
这能回答你的问题吗? An aggregate may not appear in the WHERE clause unless it is in a subquery 【参考方案1】:我认为您要编写的查询类似于:
select p.prod_cat, t.avg_total_amount
from (
select prod_cat_code, avg(total_amount) as avg_total_amount
from transactions
group by prod_cat_code
having avg(total_amount) > (select avg(total_amount) from transactions)
) t
inner join prod_cat_info p on p.prod_cat_code = t.prod_cat_code
子查询按类别聚合交易,计算平均值,并将其与整体交易平均值进行比较。然后我们只需将类别表与连接一起带入。
【讨论】:
【参考方案2】:我建议使用窗口函数。目前尚不清楚您所说的“平均总收入”是什么意思。如果您指的是产品总收入的平均值,那么:
SELECT *
FROM (SELECT P.prod_cat, SUM(total_amount) as total_revenue,
AVG(SUM(total_amount)) OVER () as avg_total_revenue
FROM [dbo].[Transactions] T JOIN
[dbo].[prod_cat_info] P
ON T.prod_cat_code=P.prod_cat_code
GROUP BY P.prod_cat
) c
WHERE total_revenue > avg_total_revenue;
如果您指的是产品平均值与总体平均值相比:
SELECT *
FROM (SELECT P.prod_cat, AVG(total_amount) as avg_revenue,
SUM(SUM(total_amount)) OVER () / SUM(COUNT(*)) as avg_total_revenue
FROM [dbo].[Transactions] T JOIN
[dbo].[prod_cat_info] P
ON T.prod_cat_code=P.prod_cat_code
GROUP BY P.prod_cat
) c
WHERE avg_revenue > avg_total_revenue
【讨论】:
【参考方案3】:以下查询解决了我的问题。
WITH cte_avg AS (SELECT P.prod_cat, Avg_revenue = AVG(CAST(T.total_amt AS NUMERIC))
FROM [dbo].[Transactions] AS T
LEFT JOIN [dbo].[prod_cat_info] AS P ON T.prod_cat_code=P.prod_cat_code
GROUP BY P.prod_cat)
SELECT prod_cat, Avg_revenue
FROM cte_avg
WHERE Avg_revenue>(SELECT AVG(Avg_revenue) FROM cte_avg)
【讨论】:
以上是关于SQL - 聚合可能不会出现在 WHERE 子句中,除非它位于 HAVING 子句中包含的子查询中的主要内容,如果未能解决你的问题,请参考以下文章
DB2中where子句中用了1=1的话,会不会导致索引失效,请详细说明.