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

どこでも奇妙

    更新 :MySQLの> ALLをさらに分析して展開すると 奇妙な実装。この回答は、MySQL固有と見なす必要があります。したがって、さらなる免責事項については、> ALLに関するここでの回答の説明 他のRDBMSには適用されません(MySQL実装をコピーした他のRDBMSがない場合)。 > ALLからの内部翻訳 MAXに 構築、MySQLにのみ適用されます。

    これ:

    select id from t1 where id > all (select id from t2); 
    

    意味的には次と同等です:

    select id from t1 where id > (select max(id) from t2); 
    

    select max(id) from t2 1を返し、2番目のクエリはこれに具体化します:

    select id from t1 where id > 1
    

    そのため、両方の10が返されます および2 テーブルt1から

    NULLルールが適用されている例の1つは、NOT INを使用する場合です。 、例:

    DDL:

    create table t1(id int);
    
    insert into t1 values (10),(2);
    
    
    create table t2(id int); 
    
    insert into t2 values (0),(null),(1);
    

    クエリ:

    select * from t1 where id not in (select id from t2);
    
    -- above is evaluated same as the following query, so the rules about null applies,
    -- hence the above and following query will not return any record.    
    
    select * from t1 where id <> 0 and id <> null and id <> 1;
    
    
    
    -- to eliminate null side-effect, do this:
    select * from t1 where id not in (select id from t2 where id is not null);
    
    -- which is equivalent to this:
    select * from t1 where id <> 0 and id <> 1;
    

    最後の2つのクエリは10を返します および2 、一方、最初の2つのクエリは空のセットを返します

    ライブテスト: http://www.sqlfiddle.com/#!2/82865/ 1

    これらの例がNULLルールとの混乱を解消することを願っています。

    について

    最適化されたSQLは次のとおりです:

    select `test`.`t1`.`id` AS `id` from `test`.`t1` where <not>((`
    test`.`t1`.`id` <= (select max(`test`.`t2`.`id`) from `test`.`t2`)))
    

    これは、元のクエリと実際に同じです。select id from t1 where id > all (select id from t2);

    コンストラクトt1.field > all (select t2.field from t2) は単なる構文糖衣です:

    t1.field > (select max(t2.field) from t2)
    

    MySqlによって最適化されたSQLにドモルガンの定理を適用する場合:

    not (t1.id <= (select max(t2.id) from t2))
    

    これは次と同等です:

    t1.id > (select max(t2.id) from t2)
    

    これは、構文糖衣ALLと同等です。 :

    t1.id > ALL(select t2.id from t2)
    


    1. 一意のインデックス値をオーバーライドする

    2. MySQLで選択した値をマッピングする

    3. 名前がJPAの予約語であるエンティティフィールドをマップする方法

    4. T-SQL:MAX(その他の列)に基づく列の選択