我刚刚升级到mysql 5.7.14并且导致我的一个查询出现问题,我收到了错误。
#1055 - SELECT列表的表达式#1不在GROUP BY子句中,并且包含非聚合列'salesinvoice.InvoiceDate' 它在功能上不依赖于GROUP BY子句中的列; 这与sql_mode = only_full_group_by
不兼容
现在解决方案显然是编辑my.ini文件并添加此行
sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
现在这个工作了,现在我的查询运行正常,但我宁愿让我的查询符合mysql 5.7,而不是必须在我的ini文件中添加行,这可能会或可能不会在我们的服务器上运行。我无法访问服务器上的ini文件,但我在本地服务器上运行wampserver 3.06。
这是我的查询
SELECT DATE_FORMAT(`InvoiceDate`,'%Y-%m') as InvoiceDate,
ROUND((SUM(`Unit_Cost`*`Quantity`)*`ExchangeRate`)+`VATValue`,2) as amount
FROM `salesinvoice`
LEFT JOIN `salesinvoice_products`
on `salesinvoice`.`SalesInvoice_id`=`salesinvoice_products`.`SalesInvoice_id`
WHERE `InvoiceDate` < Now()
and `InvoiceDate` > DATE_ADD(Now(), INTERVAL- 6 MONTH)
GROUP BY Month(`InvoiceDate`)
如何将我的查询更改为符合mysql 5.7,以及错误消息的真正含义是什么?
答案 0 :(得分:1)
你的ActInvoiceDate很有气氛......
您无法在哪里使用别名,您应该更改别名的名称 (并且你应该在分组中使用相同的列)
您的查询之前工作正常,因为之前的版本没有检查select by子句中是否有选择的列不相符... 这些列在需要时使用firts值dound
所以你有一个不在分组中的ExchangeRate,VATValue列你可以使用(假)聚合函数(在这种情况下我使用min),因为这些列可能具有常量值
SELECT
DATE_FORMAT(`InvoiceDate`,'%Y-%m') as ActInvoiceDate
,ROUND((SUM(`Unit_Cost`*`Quantity`)*min(`ExchangeRate`)+min(`VATValue`),2) as amount
FROM `salesinvoice`
LEFT JOIN `salesinvoice_products` on `salesinvoice`.`SalesInvoice_id`=`salesinvoice_products`.`SalesInvoice_id`
WHERE `InvoiceDate` < Now() and `InvoiceDate` > DATE_ADD(Now(), INTERVAL- 6 MONTH)
GROUP BY DATE_FORMAT(`InvoiceDate`,'%Y-%m')
或
SELECT
DATE_FORMAT(`InvoiceDate`,'%Y-%m') as ActInvoiceDate
,ROUND((SUM(`Unit_Cost`*`Quantity`)*min(`ExchangeRate`))+min(`VATValue`),2) as amount
FROM `salesinvoice`
LEFT JOIN `salesinvoice_products` on `salesinvoice`.`SalesInvoice_id`=`salesinvoice_products`.`SalesInvoice_id`
WHERE `InvoiceDate` < Now() and `InvoiceDate` > DATE_ADD(Now(), INTERVAL- 6 MONTH)
GROUP BY ActInvoiceDate
答案 1 :(得分:1)
来自MySQL文档
MySQL 5.7.5 及以上实现功能依赖的检测。如果 启用了
ONLY_FULL_GROUP_BY
SQL模式(默认情况下是这样), MySQL拒绝选择列表HAVING
条件或的条件的查询ORDER BY
列表引用既未命名的非聚合列GROUP BY
子句在功能上也不依赖于它们。 (的之前 5.7.5,MySQL 不检测功能依赖性,默认情况下未启用ONLY_FULL_GROUP_BY
。
要告诉MySQL接受查询,您可以在产生错误的字段上使用ANY_VALUE()
函数。
SELECT ANY_VALUE(DATE_FORMAT(`InvoiceDate`,'%Y-%m')) as `formatedInvoiceDate`,
ROUND((SUM(`Unit_Cost`*`Quantity`)*`ExchangeRate`)+`VATValue`,2) as `amount`
FROM `salesinvoice`
LEFT JOIN `salesinvoice_products`
on `salesinvoice`.`SalesInvoice_id`=`salesinvoice_products`.`SalesInvoice_id`
WHERE `InvoiceDate` < Now()
and `InvoiceDate` > DATE_ADD(Now(), INTERVAL- 6 MONTH)
GROUP BY Month(`InvoiceDate`).
或者,禁用ONLY_FULL_GROUP_BY
。
可以在Miscellaneous Functions上的MySQL文档中找到关于ANY_VALUE()
函数的更多信息(请务必阅读示例)。
同样,
ANY_VALUE()
函数对于GROUP BY
查询非常有用ONLY_FULL_GROUP_BY
启用SQL模式,以防MySQL拒绝a 您知道的查询是有效的,因为MySQL无法确定。 函数返回值和类型与返回值相同 和其参数的类型,但不检查函数结果ONLY_FULL_GROUP_BY
SQL模式。
答案 2 :(得分:0)
模式是否依赖于数据库或连接?
模式未链接到特定数据库。模式可以在本地设置为会话(连接),也可以全局设置为服务器。您 可以使用SET [GLOBAL|SESSION] sql_mode='modes'更改这些设置。
在许多平台上,可以在连接上运行默认查询。
说默认模式更严格,不再允许不完整的GROUP BY子句,因为它通常表示查询错误且结果不正确。
答案 3 :(得分:0)
您可以使用此语句设置sql_mode
SET GLOBAL sql_mode="STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION";