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

SQLのunion句

    この答えは少しとりとめのないかもしれません...

    Oracleは非常に セット操作でうるさい。すべての列は、2番目、3番目などのクエリの対応する列と同じデータ型である必要があります。

    私は考えます Oracleがto_number()を評価するため、2番目のクエリは失敗します 数値として unionを実行する ただし、の「null-ness」について評価します。 。最初の値が「null-ness」について評価され、次に union が評価されたため、最初のクエリは成功します。 発生します。これは、評価の順序が次のとおりであることを意味します。

    1. 最初の選択機能
    2. 最初に選択したデータ型
    3. 2番目の選択機能
    4. ユニオン
    5. 2番目に選択したデータ型

    これを段階的に証明しようとしますが、絶対的な証明になるかどうかはわかりません。

    次の両方のクエリ

    select 1 from dual union select '1' from dual;
    select '1' from dual union select 1 from dual;
    

    暗黙的な変換が行われないため、次のエラーで失敗します。

    ただし、次の両方が成功します

    select null from dual union select '1' from dual;
    select null from dual union select 1 from dual;
    

    ダンプ> これら2つのクエリのうち、次のものが返されます。

    SQL> select dump(a)
      2    from ( select null a from dual union select '1' from dual );
    
    DUMP(A)
    -------------------------------------------------------------------
    
    Typ=96 Len=1: 49
    NULL
    
    SQL> select dump(a)
      2    from ( select null a from dual union select 1 from dual );
    
    DUMP(A)
    -------------------------------------------------------------------
    
    Typ=2 Len=2: 193,2
    NULL
    

    ご覧のとおり、列にはさまざまなデータ型があります。 。文字を含む最初のクエリは、 charを返します 2番目は数値を返しますが、2番目の select を使用して、順序が逆になっています。 最初に来る。

    最後に、 dumpを見ると 最初のクエリの

    SQL> select substr(dump(ename),1,35) a, substr(dump(loc),1,35) b
      2    from ( select ename,to_number(null) as loc from emp
      3            union
      4           select to_char(null),loc from dept
      5                  );
    
    A                                   B
    ----------------------------------- -----------------------------------
    Typ=1 Len=6: 104,97,104,97,104,97   NULL
    NULL                                Typ=1 Len=6: 104,97,104,97,104,97
    
    SQL>
    

    dump(to_number(null))が表示されます。 無効です;しかし、 varchar2 charではありません これは列のデータ型であるため、が返されます。返されるステートメントの順序が逆になっておらず、このクエリをテーブルとして作成する場合、両方の列が varchar2になることに注意してください。 。

    選択クエリの列のデータ型を決定するとき、Oracleは最初の既知のデータ型を取得し、それを使用して全体のデータ型を計算します。これが、最初の selectでクエリを実行する理由です。 nullだったので、行が逆になりました。

    最初のselect、 select ename、to_number(null)from emp が原因で、最初のクエリは成功します。 、結果セットがどのようになるかを「説明」します。 | varchar2 | null | 。次に、2番目のクエリは | varchar2 | varchar2 |を追加します。 、問題は発生しません。

    最初のselectselect ename、to_number(null)from emp が原因で、2番目のクエリは失敗します。 結果セットをvarchar2、nullとして「記述」します 。ただし、 unionにnull番号とvarchar2を追加しようとします。 。

    ここでの信頼の飛躍は、Oracleが to_number(null)を決定していることです。 は前の番号です ユニオンへ そしてそれが「ヌル性」であるかどうかを評価するのは後になるまでです。 null でオブジェクトを作成できないため、これが実際に発生しているかどうかをテストする方法がわかりません。 列とあなたが注意するようにあなたもそれを選択することはできません。

    オラクルが許可していないことを証明できないので、経験的な証拠を探します。次のクエリの結果(またはエラー)を考慮してください。

    SQL> select 1 as a from dual union select to_number(null) from dual;
    
             A
    ----------
             1
    
    
    SQL> select '1' as a from dual union select to_number(null) from dual;
    select '1' as a from dual union select to_number(null) from dual
           *
    ERROR at line 1:
    ORA-01790: expression must have same datatype as corresponding expression
    
    
    SQL> select 1 as a from dual union select to_char(null) from dual;
    select 1 as a from dual union select to_char(null) from dual
           *
    ERROR at line 1:
    ORA-01790: expression must have same datatype as corresponding expression
    
    
    SQL> select '1' as a from dual union select to_char(null) from dual;
    
    A
    -
    1
    

    to_char およびto_number 、nullで実行されるかどうかに関係なく、データ型を暗黙的に定義し、 unionでその適切性が評価されます。 、「null-ness」の評価前

    この説明では、 coalesceについても説明します。 to_number(null)として発行 の数字です ヌルです。




    1. 改行のある列名

    2. Mysqlの「VALUES関数」は非推奨になりました

    3. 各グループの上位1行を取得

    4. SQLServerでNull値が取るサイズ