SQL的GROUP BY和HAVING

3
所以我不明白为什么一直出现这个错误。
 select distinct substr(CUSTZIP, 1,5), AVG(CUSTBAL), custcity, custstate
 from customer
 group by CUSTCITY, custstate
 having CUSTSTATE = 'wa' AND avg(CUSTBAL) >100;

错误提示为“不是 GROUP BY 表达式”,建议在 group by 子句中添加 'substr(CUSTZIP, 1,5), AVG(CUSTBAL)',但这也不起作用。 我想做的是仅列出华盛顿州城市的邮政编码和平均余额,并且余额超过100美元。 有人能帮忙指出我的错误吗?我相信这很简单,但我在初学者水平上似乎无法理解。

1
如果你使用GROUP BY,你就不需要DISTINCT。 - Raj More
3个回答

1
你收到的错误是因为你正在尝试执行聚合操作(即sumavg等),但没有将所有列包含在select子句中,并添加到group by子句中。如果你选择了该列,则在使用聚合函数时也应该按该列进行分组。

在你的特定情况下,你需要将substr(custzip, 1,5)添加到你的group by子句中。

select substr(custzip, 1,5), custcity, custstate, avg(custbal)
from customer
where custstate = 'wa'
group by substr(custzip, 1,5), custcity, custstate
having avg(custbal) > 100;

另外,请注意,您可以删除distinct,因为group by也会处理它。我还将custstate = 'wa'移至WHERE条件中。由于WHEREHAVING之前执行,它将减少需要聚合的结果数量。

1
问题不在于having子句,而在于substr(CUSTZIP, 1, 5)。以下是解决问题的一种方法:
select substr(CUSTZIP, 1, 5), AVG(CUSTBAL), custcity, custstate
from customer
group by CUSTCITY, custstate, substr(CUSTZIP, 1, 5)
having CUSTSTATE = 'wa' AND avg(CUSTBAL) > 100;

顺便提一下,select distinct 几乎不需要与 group by 一起使用。

或者,您可以使用聚合函数:

select max(substr(CUSTZIP, 1, 5)), AVG(CUSTBAL), custcity, custstate
from customer
group by CUSTCITY, custstate
having CUSTSTATE = 'wa' AND avg(CUSTBAL) > 100;

好奇,distinct何时会与group by一起使用?另外,把非聚合条件放在where从句中而不是having,这不是最佳实践吗? - sgeddes
distinct 是一个错误。你能解释一下为什么 substr(custzip,1,5) 放在 group by 子句的末尾而不是中间或前面时它能够工作吗?或者我完全做错了什么? - Restnom
@Restnom -- 在 selectgroup by 子句中列的顺序是无关紧要的。您只需要确保在使用聚合函数(例如 avg())时,非聚合列包含在 group by 子句中。在这种情况下,substr(custzip, 1,5) 被遗漏了。 - sgeddes
@Restnom . . . 在第一种情况下,substr() 表达式在 group by 中,这就是为什么它有效的原因。而在第二种情况下,它在聚合函数中。这与 selectgroup by 中表达式的顺序无关。 - Gordon Linoff

0

以下是一些建议:

  1. 您应该采纳将 substr(CUSTZIP, 1,5) 和 AVG(CUSTBAL) 添加到 group by 子句的建议。

  2. 请注意 distinct 和 group by 的使用,以及 having 子句的用法。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接