使用带聚合函数的联结,在分组GROUP BY时的疑点

最近遇到了这样的代码问题,问一问大咖们,请详细解答。
在 SQL 查询中,如果 SELECT 子句中包含了聚合函数(如 COUNT、SUM、AVG 等),那么除了聚合函数之外的列都必须在 GROUP BY 子句中出现。这是因为 GROUP BY 子句用于指定按哪些列进行分组
那么这里为什么一个列就够了?

        SELECT customers.cust_name,
                    customers.cust_id,
                   COUNT(orders.order_num) AS num_ord
    FROM customers INNER JOIN orders
    ON customers.cust_id = orders.cust_id
    GROUP BY customers.cust_id;

其中GROUP BY 子句 就写了一个列customers.cust_id
显示结果如下:

img



为什么这里只需要一个列呢?
当然这种写法肯定是没问题的

        SELECT customers.cust_name,
                    customers.cust_id,
                   COUNT(orders.order_num) AS num_ord
    FROM customers INNER JOIN orders
    ON customers.cust_id = orders.cust_id
    GROUP BY customers.cust_name, customers.cust_id;

也就是多加了一列customers.cust_name,这样就符合除了聚合函数之外的列都必须在 GROUP BY 子句中出现,这句话的要求
显示结果如下:

img



如果一个列就够了那么为什么这样写的时候就报错呢?把最后面的customers.cust_id改成了customers.cust_name.

        SELECT customers.cust_name,
                    customers.cust_id,
                   COUNT(orders.order_num) AS num_ord
    FROM customers INNER JOIN orders
    ON customers.cust_id = orders.cust_id
    GROUP BY customers.cust_name;
  
报错信息:Expression #2 of SELECT list is not in GROUP BY clause and contains nonaggregated column
                  'crashcourse.customers.cust_id'
                 which is not functionally dependent on columns in GROUP BY clause; 
                 this is incompatible with sql_mode=only_full_group_by

报错信息的大致意思是要包含非聚集的列在GROUP BY子句中,也就是说要写成GROUP BY customers.cust_name, customers.cust_id 这样才行
那么问题来了,为啥cust_id 可以,cust_name就不行呢?是不是因为cust_id在两张表都有,且有唯一性,而cust_name只在customers表中,orders表中并没有这列。所以不能根据cust_name进行分组。请解释原因。
附上这两张表,customers和orders截图

img



img

引用 皆我百晓生 小程序回复内容作答:
在SQL查询中,如果SELECT子句中包含了聚合函数,那么除了聚合函数之外的列都必须在GROUP BY子句中出现。这是因为GROUP BY子句用于指定按哪些列进行分组。在给定的例子中,将GROUP BY子句设置为"customers.cust_id"是符合语法的。

第一个查询中,只选择了一个列"customers.cust_id"作为GROUP BY子句。这是因为该查询的目的是根据顾客ID对订单进行分组,并计算每个顾客的订单数量COUNT(orders.order_num)。查询结果将按照顾客ID进行分组,并为每个组显示顾客的名称、顾客ID和订单数量。由于其他列没有被选择为GROUP BY子句的一部分,它们将不会影响分组的方式。

第二个查询中,将两个列"customers.cust_name"和"customers.cust_id"作为GROUP BY子句。这是符合要求的,因为除了聚合函数之外的所有列都必须在GROUP BY子句中出现。

第三个查询中出现了错误。报错信息表明,SELECT列表中的表达式#2不在GROUP BY子句中,并且包含了非聚合的列"crashcourse.customers.cust_id"。这是因为在只使用了"customers.cust_name"作为GROUP BY子句时,查询引擎无法确定如何对每个顾客进行分组,因为每个顾客可能具有多个不同的"customers.cust_id"值。在这种情况下,查询引擎要求所有没有被聚合的列都出现在GROUP BY子句中,以确保结果集的一致性。

总而言之,除非使用聚合函数,否则在GROUP BY子句中,必须包含所有不同的列,以确保正确的分组和结果集。在给定的示例中,由于"customers.cust_name"列只存在于"customers"表中,而"customers.cust_id"在两个表中都存在且具有唯一性,因此无法根据"customers.cust_name"进行分组。