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

MySQLの1つのフィールドに対してのみWHERE句を表示する方法はありますか?

    MySQL 5.7より前のデフォルトでは、完全でないgroup byを許可していました。 。つまり、group by(sumなどの集計関数を使用)を作成できます。 およびmax およびcount およびgroup_concat )他の非集計列(NON AGGSと呼びましょう) )最初の3つが表示されているようにすべてではありません group byの一部 句。それはそれを可能にしましたが、結果は通常次のようになります:

    • あなたはあなたのデータをよく知っていて、明確なものを達成しようとしているので、それはうまくいきました

    • それはスナフだったのでひどい結果になりました

    5.7より前のバージョンでは、ONLY_FULL_GROUP_BY 存在しましたが、デフォルトでオフになっています。

    したがって、MySQL 5.7には、ONLY_FULL_GROUP_BYが付属しています。 デフォルトはオンです。そのため、グループ化を試みる場合、ただしすべてではない NON AGGS group by 句を指定すると、エラーが発生します。

    以下の5.6の次の問題を検討してください。

    create table thing
    (   col1 int not null,
        col2 int not null,
        age int not null
    );
    insert thing(col1,col2,age) values 
    (1,2,10),
    (1,3,20),
    (2,3,20),
    (2,2,10);
    
    select col1,col2,max(age) from thing group by col1;
    +------+------+----------+
    | col1 | col2 | max(age) |
    +------+------+----------+
    |    1 |    2 |       20 |
    |    2 |    3 |       20 |
    +------+------+----------+
    

    上記で発生するのは、すべてのNON AGGSではありません。 group byに含まれています 。 max(age)をcol1で返します。しかし、col2以降 group byに含まれていませんでした 、クラスターインデックスまたは物理順序を使用して、誤って(snafu、間違い)col2の値を間違えました。あなたの意図に応じて、またはあなたのデータを知っているか、あるいは思いやりさえあります。エンジンは気にしませんでした。おそらくあなたはそうします。

    これらの一般的な間違いや不注意によるデータの返送を回避するために、MySQL5.7はONLY_FULL_GROUP_BYをオンにします。 デフォルトで。

    あなたの場合、間違った行がおそらく列2と3の結果を構成しています。

    MySQLによるGROUPBYの処理<というタイトルのマニュアルページを参照してください。 / a> 。

    例2

    -- drop table if exists person;
    create table person
    (   id int auto_increment primary key,
        firstName varchar(100) not null,
        lastName varchar(100) not null
    );
    
    -- drop table if exists fruitConsumed;
    create table fruitConsumed
    (   id int auto_increment primary key,
        theDate date not null,
        fruitId int not null, -- does not really matter. Say, 1=apple, 2=orange from some other table
        personId int not null,
        qty int not null
    );
    
    -- truncate table person;
    insert person (firstName,lastName) values 
    ('Dirk','Peters'),
    ('Dirk','Smith'),
    ('Jane','Billings');
    
    -- truncate table fruitConsumed;
    insert fruitConsumed (theDate,fruitId,personId,qty) values
    ('2016-10-31',1,1,2),
    ('2016-10-31',2,1,5),
    ('2016-10-31',2,2,12),
    ('2016-11-02',2,2,3);
    

    クエリ:

    select p.firstName,p.lastName,sum(fc.qty) 
    from person p 
    join fruitConsumed fc 
    on fc.personId=p.id 
    group by p.firstName,p.lastName; 
    +-----------+----------+-------------+
    | firstName | lastName | sum(fc.qty) |
    +-----------+----------+-------------+
    | Dirk      | Peters   |           7 |
    | Dirk      | Smith    |          15 |
    +-----------+----------+-------------+
    

    上記は、ONLY_FULL_GROUP_BYの設定に関係なく、MySQL5.6および5.7でうまく機能します。

    今考えてください

    select p.firstName,p.lastName,sum(fc.qty) 
    from person p 
    join fruitConsumed fc 
    on fc.personId=p.id 
    group by p.firstName; 
    
    +-----------+----------+-------------+
    | firstName | lastName | sum(fc.qty) |
    +-----------+----------+-------------+
    | Dirk      | Peters   |          22 |
    +-----------+----------+-------------+
    

    上記は、ONLY_FULL_GROUP_BYがなくてもMySQL5.6で受け入れられることがよくあります。 5.7で有効になり、ONLY_FULL_GROUP_BYで失敗します 有効(エラー1055)。上記の出力は基本的にぎこちないものです。しかし、以下でいくらか説明されています:

    私たちは、Dirk、Dirk、たった1つのDirkが、内部結合を生き残る唯一のDirkであることを知っています。 2つのダークがあります。しかし、group by p.firstNameのため、 、Dirkが1つだけ残っています。 lastNameが必要です 。
    SQL標準に準拠していないため、MySQLはONLY_FULL_GROUP_BYでこれを許可できます。 オフになりました。したがって、古いlastNameを選択するだけです。さて、それが最初に見つけたもの、そしてそれはキャッシュまたは物理的な順序のいずれかにあります。

    そしてそれはピーターズと一緒に行きました。フルーツカウントの合計は、すべてのダークに適用されます。

    したがって、このようにコーディングすると、不適合の非ONLY_FULL_GROUP_BY ぎこちないものになります。

    そして述べたように、MySQL5.7の出荷はデフォルトでこれを許可していません。ただし、必要に応じて、古い方法に調整できます。

    クエリを修正し、ONLY_FULL_GROUP_BYのままにすることを強くお勧めします 有効になっています。



    1. SQLで2つの列を乗算する方法

    2. MySQLまたはMariaDBGaleraClusterを使用したCamundaBPMのデータベースの高可用性

    3. PostgreSQL/MySQLで文字列から部分文字列を抽出する方法

    4. データセットをディープコピーし、すべてのコピーを指すようにFK参照を変更するにはどうすればよいですか?