使用having子句出现错误

9
select SUM (Bill) from ProductSaleReport group by PCI 
having MONTH(Date) between 1 and 3

请问有人能帮我找到问题吗?

我收到以下错误信息:

Msg 8121, Level 16, State 1, Line 1
因为它既不包含聚合函数也不在GROUP BY子句中,所以“ProductSaleReport.Date”列在HAVING子句中无效。
Msg 8121, Level 16, State 1, Line 1
因为它既不包含聚合函数也不在GROUP BY子句中,所以“ProductSaleReport.Date”列在HAVING子句中无效。


好的,出了什么错误?虽然看起来你没有使用任何聚合函数 - 也许你应该使用WHERE语句呢? - Dmitri
我已更新我的问题,并附上了错误信息,请查看一下。 - Shine
阅读以更好地了解WHERE和GROUP BY之间的区别http://www.databasejournal.com/features/mysql/article.php/3469351/The-HAVING-and-GROUP-BY-SQL-clauses.htm - niktrs
4个回答

15

MONTH(Date)不是您按组分组的列,因此它不能出现在having子句中。 你可以这样做:

select SUM (Bill) 
from ProductSaleReport
where MONTH(Date) between 1 and 3
group by PCI 

另一种方法是

select SUM (Bill) 
from ProductSaleReport 
group by PCI, MONTH(Date) 
having MONTH(Date) between 1 and 3

请记住,您将按月和PCI分组获得结果。

WHERE和HAVING的区别在这里解释:在where子句中使用“case表达式列”


1
第二个版本应该更高效! - iDevlop
@marc_s 这段示例代码对我有效:SELECT fiscalmonth,count(*) from inbalance where fiscalyear=2011 group by fiscalmonth having fiscalmonth between 1 and 3 - niktrs
1
@marc_s,你看到那些“或者GROUP BY子句”的词了吗?如果你按月份(MONTH(Date))分组,就可以在HAVING中使用它。 - Andrei Petrenko
珍珠,@Andrei 写的两个都可以工作,但要注意使用“having”与“where”子句会提供不同的结果,因为它还按月份分组。 - niktrs
@niktrs 看起来结果会是一样的。也许我错过了什么。请给出更多细节。 - Andrei Petrenko
@Andrei 第一个查询将返回 PCI * MONTH 行数,因为它按月份和 PCI 进行分组,而第二个查询将仅按 PCI 分组,并返回 PCI 行数。 - niktrs

8

使用WHERE在分组之前进行过滤

HAVING用于在分组之后过滤数据

select SUM (Bill) -- comment: you need to add the PCI column since you use it in the group by right?
from ProductSaleReport 
WHERE MONTH(Date) between 1 and 3
group by PCI 

2
MONTH(Date)不是您选择的列,因此不能出现在您的HAVING子句中。
如果您只想从月份在1和3之间的行中SUM计费,则应使用WHERE子句而不是HAVING子句。
如果每个PCI组中的所有行都具有相同的MONTH(Date),则可以将MONTH(Date)添加到您的SELECT子句中,以便在HAVING子句中使用它。

我需要根据PCI值对数据进行分组。 在PCI记录组中,我需要查找账单日期为1月、2月和3月的账单总额。 - Shine
@Andrei 看看 SQL Server 手册中的示例... http://msdn.microsoft.com/en-us/library/ms180199.aspx 。HAVING 子句作用于结果集,不管结果集是如何产生的,没有在 GROUP BY 子句中的列也可以在结果集中,并且可以在 HAVING 子句中用于过滤。 - Dan Grossman
1
@Pearl 那是一个 WHERE 条件,而不是 HAVING。将 HAVING 改为 WHERE 并将其移至 GROUP BY 之前。 - Dan Grossman
@Andrei,不知道你在说什么,该页面上没有任何查询中的WHERE子句。 - Dan Grossman
1
@Pearl:简短故事:https://dev59.com/sGw15IYBdhLWcg3wisW-#6545685 - ypercubeᵀᴹ
显示剩余7条评论

0

试试这个:

选择 SUM(Bill) 从 ProductSaleReport 分组 by PCI 筛选 MIN(MONTH(Date))>=1 和 MAX(MONTH(Date))<=3


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