在SQL查询中包装聚合函数

时间:2014-07-14 17:53:26

标签: mysql sql group-by aggregate-functions

我有2个名为Orders和Salesperson的表,如下所示:

databse tables

并且我想检索上表中超过1个订单的所有销售人员的姓名

然后触发查询后显示错误:

SELECT Name
FROM Orders, Salesperson
WHERE Orders.salesperson_id = Salesperson.ID
GROUP BY salesperson_id
HAVING COUNT( salesperson_id ) >1

错误是:

列'名称'在选择列表中无效,因为它是     不包含在聚合函数中     GROUP BY子句。

从错误中搜索谷歌,我可以理解错误是因为Name列必须是group by语句或聚合函数的一部分。

此外,我试图理解为什么所选列必须在group by子句或聚合函数的艺术中?但是不明白。

那么,如何修复此错误?

3 个答案:

答案 0 :(得分:1)

SELECT max(Name) as Name
FROM Orders, Salesperson
WHERE Orders.salesperson_id = Salesperson.ID
GROUP BY salesperson_id
HAVING COUNT( salesperson_id ) >1

基本思想是,不在group by子句中的列现在需要在聚合函数中,因为每个salesperson_id min或max的名称可能相同,因此没有真正的区别(结果)是一样的)

示例

查看你的数据你有Dan(7)的3个条目现在当创建一个连接时,行Dan(名称)乘以3(对于每个数字1丹)然后服务器现在不会“Dan” “选择cos到服务器的3行,即使它们在语义上是相同的

也试试这个,以便你看到我在说什么:

SELECT Orders.Number,  Salesperson.Name
FROM Orders, Salesperson
WHERE Orders.salesperson_id = Salesperson.ID

就查询而言INNER JOIN是一个更好的解决方案,因为它有点是这个简单查询的标准,它应该无关紧要但在某些情况下可能会发生INNER JOIN产生更好的结果但据我所知这更多的是从现在开始,服务器应该生成相同的执行计划。

为了清楚代码,我会坚持使用INNER JOIN

答案 1 :(得分:1)

假设该名称对salesperson.id是唯一的,那么只需将其添加到您的group by子句

即可
 GROUP BY salesperson_id, salesperson.Name

否则使用任何Agg功能

 Select Min(Name)

原因是SQL并不知道每个salesperson.id有多个名称。

答案 2 :(得分:0)

为了便于阅读和正确,我通常将聚合查询分为两部分:

  1. 汇总查询
  2. 支持未包含在聚合函数中的字段的任何其他查询
  3. 所以:

    1.Aggregate query - 超过1个订单的销售人员

    SELECT salesperson_id FROM ORDERS GROUP BY salespersonId HAVING COUNT(Number) > 1

    2.使用聚合作为子查询(基本上是选择加入另一个选择)以加入任何其他字段:

    SELECT * FROM Salesperson SP INNER JOIN ( SELECT salesperson_id FROM ORDERS GROUP BY salespersonId HAVING COUNT(Number) > 1 ) AGG_QUERY ON AGG_QUERY.salesperson_id = SP.ID

    还有其他方法,例如通过聚合函数选择其他字段(如其他答案所示)。这些代码可以快速编写代码,因此如果您在时间压力下编写查询,您可能更喜欢这种方法。如果需要维护查询(因此可读),我会赞成子查询。