1055 - SELECT列表中的第一个表达式不在GROUP BY子句中,并且包含非聚合列。

我的MySQL语句在我的笔记本电脑的MySQL上正常返回(服务器版本:5.5.62-0ubuntu0.14.04.1 - (Ubuntu)),但在我的服务器上(服务器版本:5.7.26-0ubuntu0.16.04.1 - (Ubuntu))返回错误。

SELECT * 
FROM `orders` 
WHERE `mail_sent`='No' 
  AND `datetime` < DATE_SUB(NOW(), INTERVAL 15 MINUTE) 
GROUP BY `contact_id` 
ORDER BY `datetime` ASC;
1055 - SELECT列表的第一个表达式不在GROUP BY子句中,并且包含非聚合列'shop.orders.id',该列与GROUP BY子句中的列没有函数依赖关系;这与sql_mode=only_full_group_by不兼容。

1这个查询试图从具有相同contact_id的记录组中选择一个随机记录。所以这个查询毫无意义。 - Akina
我只是在寻找独特的联系人ID。 - anjanesh
1只需要一个联系人标识就可以了:SELECT contact_id FROM ... - Rick James
@anjanesh SELECT DISTINCT contact_id FROM orders - Buttle Butkus
4个回答

我认为这个问题是由于你的MySQL版本启用了严格模式。请关闭严格模式并再次尝试。

要禁用,请按照如何在本地主机(xampp)上打开/关闭MySQL严格模式?进行操作。

STRICT_TRANS_TABLES负责设置MySQL的严格模式。

要检查严格模式是否已启用,请运行以下SQL语句:

SHOW VARIABLES LIKE 'sql_mode';
如果其中一个值是STRICT_TRANS_TABLES,那么严格模式就被启用了,否则就没有。在我的情况下,它给出了这样的结果
+--------------+------------------------------------------+ 
|Variable_name |Value                                     |
+--------------+------------------------------------------+
|sql_mode      |STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION|
+--------------+------------------------------------------+
因此,在我的情况下,严格模式被启用,其中一个值是STRICT_TRANS_TABLES。 要禁用严格模式,请运行以下SQL:
set global sql_mode='';

[或者任何模式,除了STRICT_TRANS_TABLES。例如:set global sql_mode='NO_ENGINE_SUBSTITUTION';]

要重新启用严格模式,请运行以下SQL:

set global sql_mode='STRICT_TRANS_TABLES';
如果你不想禁用严格模式(strict_mode),那么你必须修改你的SQL查询以符合SQL标准。 就像这样...
SELECT
   aggregated_column,
   aggregated_column,
   aggregation_function(column),
   aggregation_function(column),
   aggregation_function(column)
FROM
  TABLE
WHERE [CLAUSE]
GROUP BY [GROUP BY FIELD]
WHILE [CLAUSE]
ORDER BY 
为了您的查询...
SELECT 
  contact_id,
  min(mail_sent),
  min(datetime),
  max(datetime),
FROM `orders` 
WHERE `mail_sent`='No' 
  AND `datetime` < DATE_SUB(NOW(), INTERVAL 15 MINUTE) 
GROUP BY `contact_id` 
ORDER BY `datetime` ASC;

如果有帮助,请告诉我。


7请将**"Kindly disable strict mode"编辑为"如果您希望允许这个无意义的查询并且可能返回不一致或不存在的结果,请关闭严格模式。"** - ypercubeᵀᴹ
4年 - 我正在更新我的MySQL服务器而不禁用strict_mode。你的第二个查询在不使用ORDER BY datetime ASC时可以正常工作。SELECT MAX(order_id) FROM orders GROUP BY contact_id ORDER BY datetime ASC;返回"ORDER BY子句不在GROUP BY子句中,并且包含非聚合列'shop.orders.datetime',它在GROUP BY子句中的列上没有功能依赖;这与sql_mode=only_full_group_by不兼容。" - anjanesh
这个是等价的吗?SELECT MAX(order_id) FROM orders GROUP BY contact_id ORDER BY MAX(datetime) ASC; - 因为这个可以工作。 - anjanesh

另一个快速修复的方法是在你的SELECT语句中使用ANY_VALUE(contact_id) as contact_id而不仅仅是contact_id。 例如:
SELECT ANY_VALUE(contact_id) as contact_id, ANY_VALUE(mail_sent) as mail_sent, ANY_VALUE(datetime) AS datetime
    WHERE ...
    GROUP BY contact_id
    ORDER BY datetime DESC 

请注意,按照分组字段(例如contact_id)进行分组时,必须使用ANY_VALUE(contact_id) AS contact_id进行选择。

您可以使用ANY_VALUE()引用非聚合列来实现相同的效果,而无需禁用ONLY_FULL_GROUP_BY。

值得阅读:https://dev.mysql.com/doc/refman/5.7/en/group-by-handling.html


将除了contact_id之外的其余列放入聚合函数中。根据我的有限经验,MySQL在处理非分组列时并不完全一致,最好的情况是它不确定性。

后来的版本中已经修复了这个问题。 - Philᵀᴹ
@Philᵀᴹ 是的,而且新的严格设置会在使用可能返回不一致/荒谬数据的查询时产生OP报告的错误。 - ypercubeᵀᴹ

在Ubuntu 20+中添加进去
/etc/mysql/my.cnf
或者在
/etc/mysql/conf.d/mysql.cnf

[mysqld]
sql_mode = ""
innodb_autoinc_lock_mode = 0
设置像这样,不再工作了
[mysqld]
sql-mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION