MySQL错误:SELECT列表不在GROUP BY子句中

时间:2016-08-01 18:01:57

标签: mysql group-by mysql-error-1055

我的查询有问题,mysql会抛出以下错误:

#1055 - Expression #66 of SELECT list is not in GROUP BY clause and 
contains nonaggregated column 's.status' which is not functionally 
dependent on columns in GROUP BY clause; this is incompatible with 
sql_mode=only_full_group_by

查询是:

select   p.*,
pd.*,
m.*,
IF(s.status, s.specials_new_products_price, null) as specials_new_products_price,
IF(s.status, s.specials_new_products_price, p.products_price) as final_price
FROM products p 
LEFT JOIN specials s ON p.products_id = s.products_id  
LEFT JOIN manufacturers m using(manufacturers_id) , 
          products_description pd,
          categories c,
          products_to_categories p2c
WHERE p.products_view = 1  
AND p.products_status = 1
AND p.products_archive = 0
AND c.virtual_categories = 0
AND p.products_id = pd.products_id
AND p.products_id = p2c.products_id
AND p2c.categories_id = c.categories_id
AND pd.language_id = 1

GROUP BY p.products_id;

4 个答案:

答案 0 :(得分:13)

使用GROUP BY时,只有在每个组中只有一个值时,才能在select-list中使用表达式。否则,您会得到不明确的查询结果。

在您的情况下,MySQL认为s.status每组可能有多个值。例如,您按p.products_id进行分组,但s.status是另一个表specials中的列,可能是与表products的一对多关系。因此,specials中可能有多个行具有相同的products_id,但status的值不同。如果是这种情况,查询使用status的值是多少?这是不明确的。

在您的数据中,您可能会限制行,以便specials中的每一行products只有一行。但MySQL无法做出这样的假设。

MySQL 5.6及更早版本允许你编写这些含糊不清的查询,相信你知道自己在做什么。但是,默认情况下,MySQL 5.7可以实现更严格的强制执行(与早期版本相比,这可以做得不那么严格)。

修复方法是遵循以下规则:选择列表中的每一列都必须属于以下三种情况之一:

  • 该列位于聚合函数内,如COUNT(),SUM(),MIN,MAX(),AVERAGE()或GROUP_CONCAT()。
  • 该列是GROUP BY子句中命名的列之一。
  • 该列在功能上取决于GROUP BY子句中指定的列。

有关更多说明,请阅读此优秀博客:Debunking GROUP BY myths

重新评论,我只能猜测,因为你还没有发布你的表定义。

我猜测products_descriptionmanufacturers在功能上依赖于products,因此可以将它们列在select-list中。但是这个假设可能不正确,我不知道你的架构。

无论如何,应使用聚合函数解决有关s.status的错误。我使用MAX()作为示例。

SELECT p.*,
pd.*,
m.*,
MAX(IF(s.status, s.specials_new_products_price, NULL)) 
  AS specials_new_products_price,
MAX(IF(s.status, s.specials_new_products_price, p.products_price)) 
  AS final_price
FROM products p 
LEFT OUTER JOIN specials s ON p.products_id = s.products_id  
INNER JOIN manufacturers m ON p.manufacturers_id = m.manufacturers_id
INNER JOIN products_description pd ON p.products_id = pd.products_id
INNER JOIN products_to_categories p2c ON p.products_id = p2c.products_id
INNER JOIN categories c ON p2c.categories_id = c.categories_id
WHERE p.products_view = 1  
AND p.products_status = 1
AND p.products_archive = 0
AND c.virtual_categories = 0
AND pd.language_id = 1
GROUP BY p.products_id;

我也以正确的方式重写你的联接。应避免逗号式连接。

答案 1 :(得分:1)

您是否正在尝试ORDER BYGROUP BY子句尝试为GROUP BY子句中的列中的每个不同值返回一行,除非您向该子句添加更多列。抛出错误是因为您有其他非聚合列未包含在子句中 - 聚合列类似于MAX(p.products_id)SUM(p.products_price)。在您的查询中,有多个行具有相同的p.product_price和不同的s.status值,因此GROUP BY没有意义。

MySQL Group处理:https://dev.mysql.com/doc/refman/5.7/en/group-by-handling.html 聚合函数:http://dev.mysql.com/doc/refman/5.7/en/group-by-functions.html

答案 2 :(得分:0)

如果你想在特定列上使用GROUP BY并获得结果的id,那么有一个很好的技巧:

SELECT `distinct_column`, MAX(`id`), MAX(`another_int_column`) FROM `table_name` GROUP BY `distinct_column`

结果:

distinct_column  id       another_int_column
Abertamy         13579    11
Adamov           17765    14
Adolfovice       2924     3
Achotín          2241     2
Babice           17772    14

现在,您可以使用distinct_column中的不同值,并使用相应行的值。

source

我认为id和another_int_column必须是唯一的,但我不确定。

答案 3 :(得分:0)

不确定为什么没有人会在s.status列中强调使用ANY_VALUE()内置函数。

查看以下内容:https://dev.mysql.com/doc/refman/8.0/en/group-by-handling.html https://dev.mysql.com/doc/refman/8.0/en/miscellaneous-functions.html#function_any-value