1

我刚刚升级到 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

4 回答 4

1

您的 ActInvoiceDate 不明确..

您不能在 where 使用 alias ,您应该更改 alias 的名称(并且您应该在 group by 中使用同一列)

您的查询之前工作正常,因为以前的版本不检查 select 中的列是否在 group by 子句中不对应 .. 并且对于此列,在需要时使用第一个值 dound

所以你有 ExchangeRate, VATValue 列不在 group by 为此你可以使用(假)聚合函数(在这种情况下我使用 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
于 2017-03-02T10:36:41.360 回答
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.

更多关于ANY_VALUE()函数的信息可以在 MySQL Documentation on Miscellaneous Functions中找到(请务必阅读示例)。

概括地说,当启用 SQL 模式时,函数对查询 ANY_VALUE()很有用,例如当 MySQL 拒绝一个你知道是有效的查询的情况下,因为 MySQL 无法确定的原因。函数返回值和类型与其参数的返回值和类型相同,但函数结果不检查SQL 模式。GROUP BYONLY_FULL_GROUP_BYONLY_FULL_GROUP_BY

于 2017-03-02T12:07:52.180 回答
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";
于 2017-03-02T10:39:45.773 回答
0

来自常见问题解答:服务器 SQL 模式

在许多平台中,可以在连接上运行默认查询。

也就是说,默认模式变得更加严格并且不再允许不完整的 GROUP BY 子句,因为这通常表明查询错误并且结果不正确。

于 2017-03-02T10:39:04.873 回答