【问题标题】:MySQL error is thrown when laravel pagination is used使用 laravel 分页时会抛出 MySQL 错误
【发布时间】:2017-08-26 18:07:22
【问题描述】:

我创建了一个数据库视图,当我对这个视图使用 laravel 分页时,它会抛出:

SQLSTATE[42000]: Syntax error or access violation: 1140 Mixing of GROUP columns (MIN(),MAX(),COUNT(),...) with no GROUP columns is illegal if there is no GROUP BY clause (SQL: select count(*) as aggregate from `parameter_log_site_detail` where `site_id` = EPE)

但此错误仅在实时服务器中弹出。分页在本地服务器上工作正常。

数据库视图: (parameter_log_site_detail)

select `t`.`site_id` AS `site_id`,cast(`t`.`logged_at` as date) AS `logged_on`,`t`.`daily_generation` AS `daily_generation`,`t`.`reading` AS `tot_reading` from `parameter_log_tab` `t` order by cast(`t`.`logged_at` as date) desc

型号:

public function scopeSiteDailyReadings($query)
{
    return $query->from('parameter_log_site_detail');
}

控制器:

$generations = EnergyGeneration::siteDailyReadings()->where('site_id', $site_id)->orderBy('logged_on', 'desc')->paginate(15);

实时服务器信息

MySQL Server version: 5.6.37 - MySQL Community Server (GPL)
PHP version: 5.6.30
Laravel version: 5.4

本地服务器信息(正常运行的地方)

MySQL Server version: 5.7.19 - MySQL Community Server (GPL)
PHP version: 7.1.7
Laravel version: 5.4

有人能解释一下这是什么原因吗?我读到了 ONLY_FULL_GROUP_BY。但不知道是不是因为服务器版本是5.6.*。

【问题讨论】:

  • 您是否检查过您的服务器上是否启用了ONLY_FULL_GROUP_BY
  • @jaysingkar 用于实时服务器 SELECT @@sql_mode 返回 NO_ENGINE_SUBSTITUTION 而在本地服务器中,它返回 ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_...
  • 从您的操作看来,ONLY_FULL_GROUP_BY 在您的服务器中被禁用,而在您的本地服务器中被启用。虽然它应该与给定的 MySQL 文档不同。 :( .. 你能不能尝试在你的服务器上启用ONLY_FULL_GROUP_BY。我知道,我在这里帮不了你太多,但我看不到任何其他问题

标签: mysql laravel laravel-pagination


【解决方案1】:

可以在 MySQL 5.6 中设置 SQL 模式 ONLY_FULL_GROUP_BY,但默认情况下不设置(参见 https://dev.mysql.com/doc/refman/5.6/en/sql-mode.html)。

啊哈,我看到您的评论出现在上面,您已经确认在您的本地服务器(MySQL 5.7)上设置了 ONLY_FULL_GROUP_BY。

我认为您在问题描述中误报了某些内容。如果本地有 ONLY_FULL_GROUP_BY 而 live 没有,您应该在本地服务器上得到错误,而不是在 live 服务器上。

我建议你确保在开发中使用与生产中使用的版本相同的版本,并匹配相同的 SQL 模式。这将防止开发过程中的混乱。

我对 PHP 的版本提出了同样的建议。如果您在开发中使用一些新的 PHP 7 功能,然后部署到您的 PHP 5.6 实时服务器,它们将无法工作。

你描述的SQL应该没问题:

select count(*) as aggregate from `parameter_log_site_detail` where `site_id` = EPE

这实际上没问题,即使您有 ONLY_FULL_GROUP_BY。对表中所有匹配的行进行select count(*) 肯定是合法的。此查询不需要 GROUP BY 子句。

但如果将聚合列与非聚合列混合使用,则会违反 ONLY_FULL_GROUP_BY 要求,因为非聚合列会不明确。

select id, count(*) as aggregate from ...

我想知道 Laravel 是否在准备查询之前将额外的列插入到您的选择列表中。您必须启用 MySQL 查询日志才能确定。

我注意到在 Laravel 问题上有一些关于这个错误的讨论:https://github.com/laravel/framework/issues/15232

该线程中的几个用户表示解决问题的解决方案是在您的 Laravel config/database.php 中设置'strict'=>false

但我敢打赌,根本原因是 Laravel 正在修改您的 SQL 查询。

【讨论】:

  • 感谢您的回复和建议。解决方案是设置'strict' => false
  • 作为我的本地服务器,我使用 Laragon 并且没有更改其配置。我在发货时使用它。但是我对实时服务器没有太多控制权。我将更改我的 MySQL 和 PHP 版本以与实时服务器同步。感谢您的建议。
猜你喜欢
  • 1970-01-01
  • 2021-02-19
  • 2017-07-11
  • 2014-11-13
  • 1970-01-01
  • 2018-03-24
  • 1970-01-01
  • 2019-02-23
  • 1970-01-01
相关资源
最近更新 更多