2017-08-24 18 views
14

我有一個名爲temp有三列一個簡單的表和以下數據:不正確的結果,當SELECT COUNT DISTINCT與ORDER BY和數學函數在MySQL 5.7.17

# c1 c2 v 
    1 1 'a' 
    1 2 'b' 
    1 1 'b' 
    1 2 'a' 

我運行查詢:

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 

這應該返回如下:

# c1, c2, cnt 
    1, 1, 2 
    1, 2, 2 

但實際上它返回:

# c1, c2, cnt 
    1, 1, 1 
    1, 2, 1 
    1, 1, 1 
    1, 2, 1 

這是奇怪的只是當它包含數學函數地板爲了通過組由計數明顯,結果是不正確 - 它不組的數據。

這是版本5.7.17中的MySQL錯誤嗎?

+1

你的問題太長。請使用一個或兩個查詢來詢問您的問題。 –

+0

它沒有'order by'工作。這很奇怪。 –

+0

子查詢中的'Floor()'似乎100%多餘,而子查詢中不包含'GROUP BY v'。也許你得到的古怪結果是由於在你的子查詢中排除了這個組? – JNevill

回答

2

它只是試圖在MySql 5.6上sqlfiddle,它只是工作。而在MySql 5.7中,它不支持 dbfiddle

所以它可能是你已經想到的MySql 5.7的東西。

根據下(在MySQL 5.7過時功能)

GROUP BY隱含排序默認MySql reference manual(即在沒有ASC 或DESC標誌符),但依賴隱式GROUP BY分揀 MySQL 5.7已被棄用。要獲得分組的 結果的特定排序順序,最好使用要生成給定的排序順序,使用 明確的ASC或DESC指示符用於GROUP BY列,或提供ORDER BY子句 。 GROUP BY排序是一個MySQL擴展,在未來版本中可能會更改 ;例如,使優化器能夠以任何它認爲最有效的方式排序分組,並避免排序開銷。


更新

我嘗試別的東西你哪些工作:

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 

這是我創建語句:

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''') 
; 

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

+1

該文檔僅供參考對於一個保證秩序,你需要定義一個'order by'子句。所以我認爲這不相關。或者你呢? –

+0

是的,我認爲這是相關的,因爲這正是描述問題部分的變化。此外,該組現在默認排序(這也解釋了爲什麼沒有排序它的工作) – davejal

+1

*組現在按默認排序(這也解釋了爲什麼沒有它的工作排序)* - 我不在這裏,但我們'我們將看到社區對此有何看法。 –

7

是的,這是一個與派生表(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;