最近遇到了这样的代码问题,问一问大咖们,请详细解答。
在 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
显示结果如下:
为什么这里只需要一个列呢?
当然这种写法肯定是没问题的
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 子句中出现,这句话的要求
显示结果如下:
如果一个列就够了那么为什么这样写的时候就报错呢?把最后面的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截图
引用 皆我百晓生 小程序回复内容作答:
在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"进行分组。