[英]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中, loc
和to_number
之間沒有數據類型兼容性,但它會執行。 另一方面,案例2失敗。 請澄清。
這個答案可能有點散漫......
Oracle對設置操作非常挑剔。 每列必須與第二個,第三個等查詢中的相應數據類型相同。
我想是因為甲骨文評估你的第二個查詢失敗to_number()
之前執行的多項union
,但評估它與后 “空性”。 您的第一個查詢成功,因為已經為“null-ness”評估了第一個值,然后發生了union
。 這意味着評估的順序是:
我將嘗試逐步證明這一點,但我不確定它是否足以證明這一點。
以下兩個查詢
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_char
和to_number
,無論它們是否在null上執行,都會隱式定義一個數據類型,然后在評估“null-ness”之前對它在union
中的適用性進行評估。
此解釋還將涵蓋coalesce
問題,因為to_number(null)
是一個數字, 在它為null 之前 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.