sql >> データベース >  >> RDS >> Mysql

MySQLGROUPBYの動作

    MySQLは行を任意に選択します。実際には、一般的に使用されるMySQLストレージエンジンは、最初のから値を返します。 物理ストレージに関して、グループ内の行。

    create table foo (id serial primary key, category varchar(10));
    
    insert into foo (category) values 
      ('foo'), ('foo'), ('foo'), ('bar'), ('bar'), ('bar');
    
    select * from foo group by category;
    
    +----+----------+
    | id | category |
    +----+----------+
    |  4 | bar      |
    |  1 | foo      |
    +----+----------+
    

    他の人々は、MySQLが恣意的で誤解を招く可能性のある結果をもたらしたとしても、このクエリを実行できることを正しく認識しています。 SQL標準、および他のほとんどのRDBMSベンダーは、この種のあいまいなGROUPBYクエリを許可していません。これは単一値ルールと呼ばれます :select-listのすべての列は、明示的にGROUP BY基準の一部であるか、集計関数内にある必要があります。 COUNT()MAX() 、など。

    MySQLはSQLモードをサポートしています ONLY_FULL_GROUP_BY これにより、SQL標準のセマンティクスに違反するクエリを実行しようとすると、MySQLはエラーを返します。

    AFAIK、SQLiteは、グループ化されたクエリであいまいな列を許可する唯一の他のRDBMSです。 SQLiteは最後から値を返します グループ内の行:

    select * from foo group by category;
    
    6|bar
    3|foo
    

    あいまいではないが、SQL標準のセマンティクスに違反しているクエリを想像することができます。

    SELECT foo.*, parent_of_foo.* 
    FROM foo JOIN parent_of_foo 
      ON (foo.parent_id = parent_of_foo.parent_id) 
    GROUP BY foo_id;
    

    これがあいまいな結果を生み出す可能性がある論理的な方法はありません。 fooの主キーでGROUPBYを実行すると、fooの各行は独自のグループを取得します。したがって、fooの列は、グループ内で1つの値しか持つことができません。グループがfooの主キーによって定義されている場合、fooの外部キーによって参照される別のテーブルに結合する場合でも、グループごとに1つの値しか持つことができません。

    MySQLとSQLiteは、論理的に明確なクエリを設計することを信頼しています。正式には、選択リストのすべての列は機能依存性である必要があります GROUPBY基準の列の数。これに従わない場合、それはあなたのせいです。 :-)

    標準SQLはより厳密であり、できた一部のクエリを許可しません。 明確にする-おそらく、RDBMSが一般的に確認するには複雑すぎるためです。



    1. Bがうまくいかない場合は、Aをロールバックします。スプリングブーツ、jdbctemplate

    2. SQLServerの文字列またはバイナリデータは切り捨てられます

    3. OracleデータベースでPL/SQL関数を作成する方法

    4. Oracleストアドプロシージャ:結果セットと出力パラメータの両方を返します