順序 - select count distinct mysql




MySQL 5.7.17のorder byおよびmath関数でselect countをdistinctにすると不正確な結果になる (2)

これはsqlfiddle MySql 5.6で試したところ、 sqlfiddle 。 また、 dbfiddle 5.7のdbfiddleではそうではありません。

あなたがすでに考えていたように、おそらくMySql 5.7のものです。

MySqlのリファレンスマニュアル (MySQL 5.7で推奨されていない機能)によると、

GROUP BYはデフォルトで暗黙的にソートされます(つまり、ASCまたはDESC指定子がない場合)が、MySQL 5.7で暗黙のGROUP BYソートに依存することは推奨されなくなりました。 グループ化された結果の特定のソート順を達成するには、指定されたソート順を生成するには、GROUP BY列に明示的なASCまたはDESC指定子を使用するか、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 : https://www.db-fiddle.com/f/7zBFKzd3pE7ymrD5LTcmkz/1

私は3つの列と次のデータを持つtempという名前のシンプルなテーブルを持っています:

# 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のバグですか?


はい、これは、外部クエリに派生テーブル( 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;  




distinct