MySQL 按问题分组 : incompatible with sql_mode=only_full_group_by

标签 mysql

任务:显示每个商店购买次数最多的产品。
3 个表:商店、产品、付款。如果销售给 1 个商店的产品有平局​​,则选择哪个产品并不重要,只需选择其中一个即可。

我对这个查询的 group by 子句有疑问:

SELECT shop_id, product_id, 
(
  SELECT COUNT(*) 
  FROM payment 
  WHERE product.product_id = payment.product_id
) sold
FROM product
GROUP BY shop_id
HAVING MAX(sold)

在 MySQL 5.6 或更低版本中,此查询可以工作。 这将是正确的结果:

shop_id | product_id | sold
1         1            3
2         3            1
3         5            1

但是在 5.7 上,我发现与 sql_mode=only_full_group_by 不兼容,因为选择中的 product_id 包含非聚合数据。

完整错误信息:

Expression #2 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'product.product_id' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by

所以我认为解决方案是像这样在组中添加 product_id:

SELECT shop_id, product_id, 
(
  SELECT COUNT(*) 
  FROM payment 
  WHERE product.product_id = payment.product_id
) sold
FROM product
GROUP BY shop_id, product_id
HAVING MAX(sold)

这修复了错误但返回了错误的结果,它不再使商店列唯一。我明白了:

shop_id | product_id | sold
1         1            3
1         2            4
2         3            1
2         4            1
3         5            1

SQLfiddle 使用 MySQL 5.6 但为了让每个人的生活更轻松:http://sqlfiddle.com/#!9/ca12bf9/6

最佳答案

您的要求出奇地复杂。您从 MySQL 对 GROUP BY 的非标准扩展中得到有用的结果完全是偶然的。基于该扩展的结果就像一头会说话的驴。效果不佳并不令人惊奇,令人惊奇的是它的效果。

这是您必须做的。

(1) 按产品和商店汇总销售额。 ( http://sqlfiddle.com/#!9/ca12bf9/12/0 )

                   select product.product_id, product.shop_id, count(*) sale_count
                     from product
                     join payment on product.product_id = payment.product_id
                    group by product.product_id, product.shop_id

(2) 通过汇总 (1) ( http://sqlfiddle.com/#!9/ca12bf9/13/0 ),找出每个商店中最畅销产品的销量

     SELECT MAX(sale_count) max_sale_count, shop_id
       FROM (
                   select product.product_id, product.shop_id, count(*) sale_count
                     from product
                     join payment on product.product_id = payment.product_id
                    group by product.product_id, product.shop_id
                 ) findmax
       GROUP BY shop_id

(3) 加入 (1) 到 (2) 以检索每个商店中销量最高的产品的标识。 ( http://sqlfiddle.com/#!9/ca12bf9/11/0 )

SELECT a.product_id, a.shop_id, b.max_sale_count
  FROM (
            select product.product_id, product.shop_id, count(*) sale_count
              from product
              join payment on product.product_id = payment.product_id
             group by product.product_id, product.shop_id    
       ) a
  JOIN (
         SELECT MAX(sale_count) max_sale_count, shop_id
                FROM (
                       select product.product_id, product.shop_id, count(*) sale_count
                         from product
                         join payment on product.product_id = payment.product_id
                        group by product.product_id, product.shop_id
                     ) findmax
               GROUP BY shop_id
       ) b ON a.shop_id = b.shop_id AND a.sale_count = b.max_sale_count

您提供的数据有平局。因此,两种不同的产品在您的一家商店中成为畅销商品。

正是这种查询将结构化置于结构化查询语言中。

关于MySQL 按问题分组 : incompatible with sql_mode=only_full_group_by,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40677595/

相关文章:

MySQL 用一条更新语句更新多条记录

MySql 查看性能

PHP 重置 $POST 值并列出所有结果

php - 如何移动上传的文件并将路径上传到mySQL数据库?使用PHP

mysql - 检测同一查询中数据库和表是否存在

php - 本地主机连接的安全性

jquery - 未发送参数时获取 MySQL 查询的所有结果

mysql - 这两个表查询的性能更好?

php - 如何将循环值传输到另一个 PHP 表

mysql - 将数据从 My Sql 导入到 Sql Server 的最简单方法