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

MySQLの「NOTIN」クエリ3テーブル

    NOT INは避けてください 疫病のように

    SELECT ID_Courses FROM Evaluation where `NAME`='JOHN' and Year=1
    

    NULLを含めることができます。代わりに、NOTEXISTSまたは左結合を使用してください

    WHERE を使用した1980年代のスタイルの結合ではなく、明示的な結合を使用します 条項

    NOT INの悲惨さを説明するために:

    SQL NOT IN()危険

    create table mStatus
    (   id int auto_increment primary key,
        status varchar(10) not null
    );
    insert mStatus (status) values ('single'),('married'),('divorced'),('widow');
    
    create table people
    (   id int auto_increment primary key,
        fullName varchar(100) not null,
        status varchar(10)  null
    );
    

    チャンク1:

    truncate table people;
    insert people (fullName,`status`) values ('John Henry','single');
    select * from mstatus where `status` not in (select status from people);
    

    **予想どおり3行**

    チャンク2:

    truncate table people;
    insert people (fullName,`status`) values ('John Henry','single'),('Kim Billings',null);
    select * from mstatus where status not in (select status from people);
    

    行がありませんね

    明らかに、これは「正しくない」です。これは、SQLが3値論理を使用していることから生じます。これは、欠落している(または不明な)情報を示す非値であるNULLの存在によって駆動されます。NOTIN、Chunk2を使用すると、次のように変換されます。

    status NOT IN ('married', 'divorced', 'widowed', NULL)
    

    これは次と同等です:

    NOT(status='single' OR status='married' OR status='widowed' OR status=NULL)
    

    式「status=NULL」はUNKNOWNと評価され、3値論理の規則に従って、NOTUNKNOWNもUNKNOWNと評価されます。その結果、すべての行が除外され、クエリは空のセットを返します。

    考えられる解決策は次のとおりです。

    select s.status
    from mstatus s
    left join people p
    on p.status=s.status
    where p.status is null
    

    または、存在しないを使用します



    1. Show_Alertを使用したOracleフォームでのモーダルウィンドウメッセージの表示

    2. AzureDataStudioを使用してSQLServerデータベースを作成する

    3. Robolectricアクセスデータベースはエラーをスローします

    4. アドホック接続文字列とMSAccessの異種クエリ