簡體   English   中英

sql中的union子句

[英]union clause in sql

給出下表描述:

emp : 

ename varchar2(25)


dept:

loc varchar2(25)

我有以下3個案例:

select ename,to_number(null) from emp
union
select to_char(null),loc from dept;

  select ename,to_number(null) from emp
    union
    select to_number(null),loc from dept;

  select ename,null from emp
    union
    select null,loc from dept;

案例1完美執行。

案例2未能執行。

案例3也完美地執行。

我的理解是,我們需要確保如果聯合沒有相應的列,那么我們需要創建一個等效的數據類型dummy。 因此, number類型在另一個表的相應列列表中具有類似to_number(null)的內容。

在案例3中,我們指定所有null,所以我有點理解該場景。 但是在情況1中, locto_number之間沒有數據類型兼容性,但它會執行。 另一方面,案例2失敗。 請澄清。

這個答案可能有點散漫......

Oracle對設置操作非常挑剔。 每列必須與第二個,第三個等查詢中的相應數據類型相同。

是因為甲骨文評估你的第二個查詢失敗to_number() 之前執行的多項union ,但評估它與 “空性”。 您的第一個查詢成功,因為已經為“null-ness”評估了第一個值,然后發生了union 這意味着評估的順序是:

  1. 第一選擇功能
  2. 第一個選擇數據類型
  3. 第二選擇功能
  4. 聯盟
  5. 第二選擇數據類型

我將嘗試逐步證明這一點,但我不確定它是否足以證明這一點。

以下兩個查詢

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

將因以下錯誤而失敗,因為不會發生隱式轉換。

ORA-01790:表達式必須與相應的表達式具有相同的數據類型

但是,以下兩個都將成功

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

如果我們選擇這兩個查詢的dump ,則會返回以下內容:

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 ,第二個查詢返回一個數字,但順序已經被轉換,第二個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))為null; 但是返回的是varchar2而不是char ,因為這是列的數據類型。 有趣的是,返回的語句的順序沒有被反轉,如果你要將這個查詢創建為一個表,那么兩列都將是一個varchar2

在選擇查詢中確定列的數據類型時,Oracle采用第一個已知數據類型,然后使用它來計算整體數據類型。 這就是為什么第一個select為null的查詢的行被反轉的原因。

您的第一個查詢成功,因為第一個選擇, select ename,to_number(null) from emp ,“描述”結果集的外觀。 |varchar2|null| 然后第二個查詢添加|varchar2|varchar2| ,這沒有問題。

您的第二個查詢失敗,因為第一個選擇select ename,to_number(null) from emp “描述”結果集為varchar2, null 然而,你再嘗試添加一個空號,並在一個VARCHAR2 union

這里的信念的飛躍是Oracle決定to_number(null)union 之前的數字,而不是直到之后才評估它為“null-ness”。 我真的不知道如何測試這是否真的發生,因為你不能創建一個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_charto_number ,無論它們是否在null上執行,都會隱式定義一個數據類型,然后在評估“null-ness”之前對它在union中的適用性進行評估。

此解釋還將涵蓋coalesce問題,因為to_number(null)是一個數字, 它為null 之前

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM