如何解决"ORDER BY子句不在SELECT列表中"导致MySQL 5.7使用SELECT DISTINCT和ORDER BY

kur*_*ama 20 php mysql

我安装了新的Ubuntu,我的代码遇到了MySQL问题.

( ! ) Warning: PDOStatement::execute(): SQLSTATE[HY000]: General error: 3065 
Expression #2 of ORDER BY clause is not in SELECT list, references column 'clicshopping_test_ui.p.products_date_added' which is not in SELECT list; this is incompatible with DISTINCT 
in /home/www//boutique/includes/OM/DbStatement.php on line 97s
Run Code Online (Sandbox Code Playgroud)

似乎MySQL 5.7不允许这样的请求:

select .... distinct with  order by rand(), p.products_date_added DESC
Run Code Online (Sandbox Code Playgroud)

如果我使用它,它的工作原理:

select distinct .... with  order by rand(), 
Run Code Online (Sandbox Code Playgroud)

如何解决这种情况?

我在PHP中的SQL请求

 $Qproduct = $OSCOM_PDO->prepare('select distinct p.products_id,
            p.products_price
            from :table_products p left join :table_specials s on p.products_id = s.products_id
            where products_status = :products_status
            and products_view = :products_view
            and p.products_archive = :products_archive
            order by rand(),
            p.products_date_added DESC
            limit :products_limit');
                  $Qproduct->bindInt(':products_status', 1);
                  $Qproduct->bindInt(':products_view', 1);
                  $Qproduct->bindInt(':products_archive', 0);
                  $Qproduct->bindInt(':products_limit', 
                  (int)MODULE_FRONT_PAGE_NEW_PRODUCTS_MAX_DISPLAY);
Run Code Online (Sandbox Code Playgroud)

Jus*_*iak 38

如果您拥有对服务器的控制权并且您正在运行遗留代码而无法轻松更改,则可以通过运行查询来调整服务器的SQL模式并在启动期间删除"only_full_group_by"

SET GLOBAL sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY',''));

或者添加sql_mode=''到my.cnf文件中.

如果你有可能,最好更改你的代码,但如果没有,这将禁用该警告.

  • @ValerianPereira 以下对我有用: SET @@sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY','')); (4认同)
  • 由于我们开发人员经常使用遗留系统,我想知道关闭“ONLY_FULL_GROUP_BY”是否存在性能问题。我发现,当我将语法修复为兼容时,与关闭“ONLY_FULL_GROUP_BY”运行它们相比,有问题的查询并没有运行得更快。我看不到通过禁用该模式来修复查询或问题有任何明显的性能优势。 (3认同)
  • 作为参考,如果您将`sql_mode =''`添加到my.cnf文件中,请务必在带有`[mysqld]`标题的新行下添加此行.例如:`[mysqld]`(换行)`sql_mode =''`.否则,在尝试重新启动`mysql`时会出现错误,例如:`mysql.service的作业失败,因为控制进程退出并显示错误代码. (2认同)
  • “如果有可能的话,显然最好更改代码,”为什么?您建议如何改变它? (2认同)

Wol*_*ack 13

要解决此问题,请打开以下文件:

/etc/mysql/mysql.conf.d/mysqld.cnf
Run Code Online (Sandbox Code Playgroud)

并在 [mysqld] 块下添加以下行

sql-mode=""
Run Code Online (Sandbox Code Playgroud)


Pau*_*NGE 13

  1. 您可以按照所述运行:
SET GLOBAL sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY',''));
SET SESSION sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY',''));
Run Code Online (Sandbox Code Playgroud)

但如果您重新启动服务器,则可能必须重新运行它。


  1. 您可以更新 mysql 服务器配置:
  • 在 Windows 上,${MY_SQL_HOME}/my.cnf(或my.ini
  • 在 Linux 上,以下之一:etc/my.cnf/etc/mysql/my.cnf/usr/etc/my.cnf~/.my.cnf
[mysqld]

# RESOLVE order-by-clause-is-not-in-select-list by removing ONLY_FULL_GROUP_BY from the sql-mode list
sql-mode="STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION"
Run Code Online (Sandbox Code Playgroud)


小智 6

如果您有 phpMyAdmin:

1-转到变量选项卡

2-搜索标签“sql模式”

3-编辑内容并删除模式:“ONLY_FULL_GROUP_BY”

4-保存

注意:不要忘记验证逗号分隔符

  • 这是可行的,但如果没有打开超级权限,则会返回错误。 (2认同)

小智 1

尝试这个:

    SELECT p.products_id,  p.products_price  
      FROM :table_products p
 LEFT JOIN :table_specials s on p.products_id = s.products_id 
     WHERE
           products_status = :products_status AND
           products_view = :products_view AND
           p.products_archive = :products_archive
  ORDER BY rand(),  p.products_date_added DESC
  GROUP BY p.products_id,p.products_price 
     LIMIT :products_limit
Run Code Online (Sandbox Code Playgroud)