Doctrine Querybuilder ORDER BY 子句不在 SELECT 列表中

Posted

技术标签:

【中文标题】Doctrine Querybuilder ORDER BY 子句不在 SELECT 列表中【英文标题】:Doctrine Querybuilder ORDER BY clause is not in SELECT list 【发布时间】:2016-06-10 19:21:43 【问题描述】:

我有以下查询生成器:

$queryBuilder = $this
    ->createQueryBuilder('recipient')
    ->leftJoin('recipient.message', 'message')
    ->orderBy('message.dateSent', 'DESC');

这一直很好 :) - 但自从升级到 mysql 5.7 后,我开始到处都出现这个错误:

SQLSTATE[HY000]: 一般错误:3065ORDER BY 子句的表达式 #1 不在 SELECT 列表中,引用列 'dctrn_result.date_sent_5' 不在 SELECT 列表中; 这与DISTINCT 不兼容

我已经在大多数使用DBAL 层的地方解决了这个问题,只需将项目添加到选择列表中,但我不知道如何使用这个特定的queryBuilder 来解决这个问题。

【问题讨论】:

描述了我找到并为我工作的一个解决方案here 【参考方案1】:

您必须通过添加以下行来编辑/etc/mysql/mysql.cnf

[mysqld]
sql-mode=""

别忘了重启服务mysql:

sudo service mysql restart

关于信息,我使用的是 Ubuntu 16.04 LTS。

【讨论】:

【参考方案2】:

添加:

[mysqld]
sql-mode=""

/etc/mysql/my.cnf 为我解决了这个问题(重启服务后)。当然,对doctrine issue 的官方回应会更好。

更新:有人比我更了解这个recommended only disabling the mode that's causing the problem.

【讨论】:

【参考方案3】:

实际上mysql 5.7在sql模式下包含'ONLY_FULL_GROUP_BY'。所以我们不能对不在选择列表中的元素执行orderby。我们必须改变它来自

'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' 

进入

'STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION'

我们可以通过执行以下查询来做到这一点

SET SESSION sql_mode = 'STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION'

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'

谢谢,

苏利亚

【讨论】:

【参考方案4】:

在#4846 中报告了一个错误,它似乎与#sqlmode_only_full_group_by 有关,并且有一些示例说明here 的含义。在找到适当的解决方案之前,解决方案是将->addSelect('message') 添加到查询中(我不知道它是否解决了问题或者学说会重写查询),但是这样学说也会为按摩提供水分,这可能是不希望的或者禁用ONLY_FULL_GROUP_BY sql模式,但是mysql可能会返回无效数据。

【讨论】:

【参考方案5】:

使用QueryBuilder 时,连接表不会自动添加到选择列表中。您可以致电addSelect(TABLE_ALIAS) 来排除错误。

$queryBuilder = $this
    ->createQueryBuilder('recipient')
    ->leftJoin('recipient.message', 'message')
    ->addSelect('message') //THIS LINE
    ->orderBy('message.dateSent', 'DESC');

【讨论】:

【参考方案6】:

将 Doctrine 更新到 2.8 应该可以解决这个问题。

【讨论】:

以上是关于Doctrine Querybuilder ORDER BY 子句不在 SELECT 列表中的主要内容,如果未能解决你的问题,请参考以下文章

学说:ORM QueryBuilder 或 DBAL QueryBuilder

在 Doctrine QueryBuilder 中计算行数

在 Doctrine QueryBuilder 中计算行数

Doctrine preLoad Listener 在执行前操纵 QueryBuilder

symfony doctrine QueryBuilder到数组结果

Doctrine Querybuilder,绑定参数