2

1つに奇妙な問題がありselectます。句の順序がWHERE結果に影響を与える可能性はありますか?

これが私の選択です:

u.userName、u.fullName、g.uuid を groupUuid、g.name を「group」として選択し、
    モジュールとして m.number、buildCount として count(distinct b.uuid)、max(b.datetime)、
    count(distinct e.buildId) を errorBuildCount として、e.id を errorId として
    ユーザーuから
    内部結合 GROUP_USER GU の GU.user_id = u.id
    内部結合 `Group` g on g.id = GU.group_id
    内部結合 Course c on c.id = g.courseId
    左外部結合 b.userId = u.id で b を構築
    m.id = b.moduleId の左外部結合モジュール m
    e.buildId = b.id の左外部結合エラー e
    c.uuid = 'HMUUcabR1S4GRTIwt3wWxzCO' および g.uuid = 'abcdefghijklmnopqrstuvwz'
    u.userName、m.number、c.uuid、g.uuid でグループ化
    g.id asc、u.fullName asc、m.number asc で並べ替え

これにより、この結果が再現されます: http://dl.dropbox.com/u/4892450/sqlSelectProblem/select1.PNG

この条件を使用する場合:

where g.uuid = 'abcdefghijklmnopqrstuvwz' and c.uuid = 'HMUUcabR1S4GRTIwt3wWxzCO' (異なる順序) 別の結果が得られます (errorId列を参照): http://dl.dropbox.com/u/4892450/sqlSelectProblem/select2.PNG

手伝っていただけませんか?選択全体が間違っていますか、それとも mysqlバグでしょうか?

4

3 に答える 3

3

結果の唯一の違いはerrorId列です。グループ化されていない列と集約されていない列は、SQL 標準 (sql-92 標準、リンクをチェックしてください) では許可されておらず、ほとんどの db エンジンでも実行されません。したがって、この状況でのエンジンの動作は指定されていません。ドキュメントによると( Marcus Adamsに感謝):

MySQL は GROUP BY の使用を拡張して、選択リストが GROUP BY 句で指定されていない非集計列を参照できるようにします。これは、前述のクエリが MySQL で有効であることを意味します。この機能を使用すると、不要な列の並べ替えやグループ化を回避してパフォーマンスを向上させることができます。ただし、これは主に、GROUP BY で指定されていない各非集計列のすべての値が各グループで同じ場合に役立ちます。サーバーは各グループから任意の値を自由に選択できるため、それらが同じでない限り、選択された値は不確定です。

errorId集計値として取得できます。

MAX(e.id) as errorId

またはそれをGROUP BYリストに含めます:

group by u.userName,m.number,c.uuid, g.uuid,e.Id

その後、クエリの結果は安定しているはずです。

参考文献:

MySQL が SQL 標準と競合する機能を追加するのはなぜですか? - SQL 標準と mysql 実装の違いの詳細な説明。( GarethDに感謝)

于 2013-03-04T15:29:06.377 に答える
1

基本的に、コードには 2 つの異なる JOIN ツリーがあります。

               user
              /    \
    group_user      build
       /              \
    group             module
       |               |
    course           error

このような構造は、特に一方のブランチの結合の結果が他方のブランチとは異なる数の一致するレコードを持つ場合、未定義の結果につながります。MySQL は、不足しているビットを埋めようとし、推測する必要があります。句の順序を変更するWHEREと、mysql が推測する方法が変更されるため、完全な結果が変更される可能性があります。

于 2013-03-04T15:30:41.167 に答える
0

集計前にすべての列でグループ化します。ベスト プラクティス...ほとんどの場合。そして、あなたの答えを歪めている可能性が非常に高いです...

于 2013-03-04T15:31:57.850 に答える