何时在“分组依据”之前使用“ WHERE”与“分组依据”之后的“使用”

问题描述

这是我的查询,仅当在分组依据之前的WHERE中使用限制性条件时才正确运行,而在分组依据之后的Haveing中使用限制性条件时才正确运行。我认为,Haveing的行为类似于Where子句,应在需要执行Group By时使用,但是下面的查询不遵循该逻辑:

/ *计算所有项目的实际总成本,这些成本不会对任何经理造成超支。显示经理的姓名,项目和各自项目的总和。

Select mg_name,p_name,sum(actual_cost),sum(expected_cost)
From Project join manager on p_manager = mg_number
Where actual_cost <= expected_cost
Group by mg_name;

下面的错误查询会在MysqL中产生错误,指出在 (错误代码:1054。“具有子句”中的未知列“ actual_cost”)

Select mg_name,sum(expected_cost)
From Project join manager on p_manager = mg_number
Group by mg_name
Having actual_cost <= expected_cost;

有人可以解释为什么第一个查询有效而第二个无效吗?

解决方法

db.collection.aggregate([ { "$project": { /* Summing goals in the Seasons list */ "seasons_goals": { "$sum": [ "$Seasons.goals" ] },/* Counting the number of seasons: length of Seasons + 2 */ "nb_seasons": { "$sum": [ { "$size": "$Seasons" },2 ] },/* Summing goals of the two last seasons */ "total": { "$sum": [ "$Last_season.goals","$Last_season_2.goals" ] } } },/* Calculate the average by dividing seasons_goals+total by nb_seasons */ { "$project": { "result": { "$divide": [ { "$sum": [ "$seasons_goals","$total" ] },"$nb_seasons" ] } } } ]) 适用于where之前的选定行(因此,总和将不包括选定的行)。 group by应用于having之后 的选定字段。它可以使用所选字段中的别名,也可以使用包含sum的表达式,因此您可以这样做:

group by

select mg_name,p_name,sum(actual_cost),sum(expected_cost)
from project join manager on p_manager=mg_number
group by mg_name
having sum(actual_cost) <= sum(expected_cost)

您可以考虑在以下情况下使用子查询的简称:

select mg_name,sum(actual_cost) manager_total_actual_cost,sum(expected_cost) manager_total_expected_cost
from project join manager on p_manager=mg_number
group by mg_name
having manager_total_actual_cost <= manager_total_expected_cost
,

您可以将HAVING与聚合函数一起使用。

基本上:

  • 具有类似于WHERE的功能,但对GROUP BY返回的分组记录进行操作。
  • HAVING适用于汇总的组记录,而WHERE适用于单个记录。
  • 仅返回符合HAVING条件的组。
  • HAVING要求存在GROUP BY子句。
  • WHERE和HAVING可以在同一查询中使用。

例如: SELECT COUNT(Id),国家 来自客户 国家“美国” 按国家分组 拥有COUNT(Id)> = 9 按COUNT(Id)DESC排序

您可以在此dofactory article

中找到有关它的很好的参考。

使用w3schools可以看到另一个很好的例子:

选择客户ID,从订单中计数(订单ID) 按客户ID分组 计数(orderid)> 1;

如果在WHERE之后尝试使用任何聚合函数,则会出现错误。 概括地说,聚合函数将在SELECT之后和HAVING之后工作,而不会在WHERE之后工作。