如何在不更改my.ini文件的情况下使我的查询符合mysql 5.7

时间:2017-03-02 10:28:21

标签: mysql mysql-error-1055

我刚刚升级到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,以及错误消息的真正含义是什么?

4 个答案:

答案 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)

来自FAQ: Server SQL Mode

  
      
  • 模式是否依赖于数据库或连接?

  •   
  • 模式未链接到特定数据库。模式可以在本地设置为会话(连接),也可以全局设置为服务器。您   可以使用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";