【问题标题】:wrapping inside aggregate function in SQL query在 SQL 查询中包装聚合函数
【发布时间】:2014-07-14 17:53:25
【问题描述】:

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

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

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

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

错误是:

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

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

我还试图理解为什么所选列必须在 group by 子句或聚合函数的艺术中?但是没看清楚。

那么,如何解决这个错误呢?

【问题讨论】:

    标签: mysql sql group-by aggregate-functions


    【解决方案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 并没有真正的区别(结果是一样的)

    示例

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

    也试试这个,让你明白我在说什么:

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

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

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

    【讨论】:

    • 我试图理解为什么所选列必须在 group by 子句或聚合函数的艺术中?但是没看清楚。可以的话请帮忙。
    【解决方案2】:

    假设名称对于 salesperson.id 是唯一的,然后只需将其添加到您的 group by 子句中

     GROUP BY salesperson_id, salesperson.Name
    

    否则使用任何 Agg 函数

     Select Min(Name)
    

    原因是SQL不知道每个salesperson.id是否有多个名字

    【讨论】:

      【解决方案3】:

      为了可读性和正确性,我通常将聚合查询分为两部分:

      1. 聚合查询
      2. 支持未包含在聚合函数中的字段的任何其他查询

      所以:

      1.聚合查询——多于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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-04-25
        • 1970-01-01
        • 1970-01-01
        • 2011-09-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多