当MySQL 5.7.17中的order by和math函数选择count时,结果不正确

gua*_*ang 15 mysql group-by distinct

我有一个简单的表,以temp三列和以下数据命名:

# c1  c2  v
  1   1  'a'
  1   2  'b'
  1   1  'b'
  1   2  'a'
Run Code Online (Sandbox Code Playgroud)

我运行查询:

SELECT
    t01.c1,
    t01.c2,
    COUNT(DISTINCT v) AS cnt
FROM
(
    SELECT 
        FLOOR(c1) AS c1,
        FLOOR(c2) AS c2,
        v
    FROM 
        temp
)   AS t01
GROUP BY
    t01.c1,
    t01.c2
ORDER BY
    cnt DESC
Run Code Online (Sandbox Code Playgroud)

这应该返回以下内容:

# c1, c2, cnt
   1,  1,  2
   1,  2,  2
Run Code Online (Sandbox Code Playgroud)

但实际上它会返回:

# c1, c2, cnt
   1,  1,  1
   1,  2,  1
   1,  1,  1
   1,  2,  1
Run Code Online (Sandbox Code Playgroud)

这很奇怪,当它包含数组不同的数学函数层次 顺序 且结果不正确时 - 它不对数据进行分组.

这是5.7.17版本中的MySQL错误吗?

oys*_*ing 9

是的,这是将派生表(FROM子句中的子查询)合并到外部查询中的错误.请在bugs.mysql.com上提交一个错误.

解决方法:

  • optimizer_switch='derived_merge=off';
  • LIMIT在子查询中添加子句.这将阻止它被合并到外部查询中.
  • 手动将子查询与外部查询合并:

SELECT 
  FLOOR(c1) AS g1, 
  FLOOR(c2) AS g2, 
  COUNT(DISTINCT v) AS cnt   
FROM temp
GROUP BY g1, g2
ORDER BY cnt DESC;  
Run Code Online (Sandbox Code Playgroud)


dav*_*jal 2

It just tried it in MySql 5.6 on sqlfiddle and it just works. And on dbfiddle in MySql 5.7 it doesn't.

So it's probably something with MySql 5.7 as you already thought.

According to MySql reference manual under (Features Deprecated in MySQL 5.7)

默认情况下,GROUP BY 隐式排序(即,在没有 ASC 或 DESC 指示符的情况下),但在 MySQL 5.7 中不推荐使用隐式 GROUP BY 排序。要实现分组结果的特定排序顺序,最好使用 GROUP BY 列使用显式 ASC 或 DESC 指示符或提供 ORDER BY 子句来生成给定排序顺序。GROUP BY 排序是 MySQL 的一个扩展,在未来的版本中可能会发生变化;例如,使优化器能够以它认为最有效的任何方式对分组进行排序,并避免排序开销。


Update:

我为你尝试了其他有效的方法:

SELECT
    t01.c1,
    t01.c2,
    count(v) AS cnt
FROM
(
    SELECT 
        DISTINCT v as v,
        FLOOR(c1) AS c1,
        FLOOR(c2) AS c2

    FROM 
        temp
)   AS t01
GROUP BY
    t01.c1,
    t01.c2
ORDER BY
    cnt DESC
Run Code Online (Sandbox Code Playgroud)

这是我的创建语句:

CREATE TABLE temp
    (`c1` int, `c2` int, `v` varchar(5))
;

INSERT INTO temp
    (`c1`, `c2`, `v`)
VALUES
    (1, 1, '''a'''),
    (1, 1, '''a'''),
    (1, 2, '''b'''),
    (1, 1, '''b'''),
    (1, 1, '''c'''),
    (1, 2, '''a''')
;
Run Code Online (Sandbox Code Playgroud)

结果: https ://www.db-fiddle.com/f/7zBFKzd3pE7ymrD5LTcmkz/1

  • 我的意思是他们在这里改变了一些东西,这可能会导致错误 (2认同)
  • 请注意,隐式排序已被弃用,而不是被删除。(它在 8.0 中被删除。)无论如何,隐式排序在这里不适用,因为有一个(显式的)ORDER BY 子句。 (2认同)