2017-08-24 25 views
0

我有兩張桌子。爲什麼Left Outer Join不能用於SQL表中不同類型的屬性?

E_Tab

E_NO E_Code Minutes 
170 01 1506 
170 40 480 
464 01 1440 
464 51 1440 
464 40 480 

二表,
P_Tab

P_No P_Code Minutes 
170 01 1506 
170 40 480 
464 01 1440 
464 51 1440 

我要的是簡單地進行左外連接。我跑這個查詢:

select * from E_Tab e 
left outer join P_Tab p 
    on e.E_No=p.P_No; 

和獲取輸出:

E_NO E_Code Minutes P_No P_Code Minutes 
170 01 1506 null null null 
170 40 480  null null null 
464 01 1440 null null null 
464 51 1440 null null null 
464 40 480  null null null 

任何人都可以請建議什麼錯誤?如何通過左外連接的方式來解決問題?謝謝。

編輯1:
E_No在Number中,P_No在varchar2中。 E_code和P_code與Minutes相同。任何人都可以建議如何修改查詢以獲得相同的預期結果嗎?

編輯2:
我想要的輸出:
E_NO E_Code Minutes P_No P_Code Minutes 170 01 1506 170 01 1506 170 40 480 170 40 480 464 01 1440 464 01 1440 464 51 1440 464 51 1440 464 40 480 null null null
很抱歉的混亂。我的查詢可能不正確。

+2

哪些數據列的類型? – MT0

+0

它似乎正常工作... – smnbbrv

+0

您的輸出中是否存在有關列E_Code的類型錯誤? – etsa

回答

2

更新版本(假設P_CODE和e_code是VARCHAR):

soelect * 
from E_Tab e 
    left outer join P_Tab p 
    on e.E_No=p.P_No 
    AND SUBSTR(E.E_CODE,2,99) = P.P_CODE 

輸出:

E_NO E_CODE MINUTES P_NO P_CODE MINUTES 
1 170 001 1506  170  01 1506 
2 170 340 480 170  40 480 
3 464 001 1440 464   01 1440 
4 464 051 1440 464   51 1440 
5 464 340 480 NULL NULL NULL 

先例答案

您發佈的查詢應禾rk,如果e_no是NUMBER且p_no是CHAR或VARCHAR,帶或不帶嵌入空格。 我想你沒有發佈你正在使用的查詢。 我可以從你的預期輸出猜你忘了

AND E.E_Code = P.P_Code 

,或者,如果你的樣本數據是正確的:

AND SUBSTR(E.E_CODE,2,99)=P.P_CODE 

在你加入條款。 此外,樣本數據中樣本輸出中的E_CODE值不相同。與您的查詢和數據輸出的

實施例,使用P_NO爲CHAR(8)的空間:

插入到p_tab值( '170',01,1506)

+--+------+--------+---------+---------+--------+---------+ 
| | E_NO | E_CODE | MINUTES | P_NO | P_CODE | MINUTES | 
+--+------+--------+---------+---------+--------+---------+ 
| | 170 | 340 |  480 | 170 |  1 | 1506 | 
| | 170 |  1 | 1506 | 170 |  1 | 1506 | 
| | 170 | 340 |  480 | 170 |  40 |  480 | 
| | 170 |  1 | 1506 | 170 |  40 |  480 | 
| | 464 | 340 |  480 | 464 |  1 | 1440 | 
| | 464 |  51 | 1440 | 464 |  1 | 1440 | 
| | 464 |  1 | 1440 | 464 |  1 | 1440 | 
| | 464 | 340 |  480 | 464 |  51 | 1440 | 
| | 464 |  51 | 1440 | 464 |  51 | 1440 | 
| | 464 |  1 | 1440 | 464 |  51 | 1440 | 
+--+------+--------+---------+---------+--------+---------+ 
+0

好的。是。但是看到不匹配的列不會爲空。 –

+0

等等?您發佈的查詢有效。檢查你在做什麼,並檢查你發佈的值。 – etsa

+0

是的查詢可能工作。但是這沒關係。當我收到錯誤時,我無法理解輸出。我需要一個不同的輸出。查詢可能需要修改。不管怎麼說,還是要謝謝你。 –

0

如果一列的數據類型爲CHAR,那麼它將右填充空格以填充列的大小。

SELECT * FROM DUAL WHERE CAST('9' AS VARCHAR2(10)) = CAST('9' AS CHAR(10)); 

將返回零行作爲'9''9 '根據Oracle的空白填充比較語義是不相等的。

blank-padded comparison semantics狀態的文檔:

隨着空白填充的語義,如果兩個值具有不同的長度,那麼Oracle首先添加到坯件的較短一個的端部,從而它們的長度是相等的。然後,Oracle逐字符地比較各個值到第一個不同的字符。在第一個不同位置具有較大字符的值被認爲更大。如果兩個值沒有不同的字符,則認爲它們是相等的。該規則意味着如果兩個值僅在尾隨空白的數量上不同,則兩個值相等。 Oracle使用空白填充比較語義只有當在比較兩個值都是由USER函數返回數據類型CHAR的任表達式,NCHAR,文本文字,或值。

在上面的例子中,比較的左手側是VARCHAR(10)和右手側是CHAR(10)然後不使用空白填充比較語義。

更新

E_No是在數量和P_No是VARCHAR2。

Oracle應該在相等性檢查中執行隱式類型轉換,它應該可以工作。

例如:

SELECT * FROM DUAL WHERE CAST('170' AS VARCHAR2(10)) = 170 
SELECT * FROM DUAL WHERE CAST(' 170' AS VARCHAR2(10)) = 170 
SELECT * FROM DUAL WHERE CAST('170 ' AS VARCHAR2(10)) = 170 
SELECT * FROM DUAL WHERE CAST('170' AS CHAR(10)) = 170 

將全部返回一行。

+0

我明白這個問題。有沒有什麼方法可以像只在查詢中暫時使用類型轉換一樣來修復它? –

+0

yesh。有用。謝謝 –

3

「E_No在數字中,P_No在varchar2中,如何修復它?」

p_no是一個字符串,所以問題可能是流浪的空間。在這種情況下,您可以修改該列並將其轉換爲數字數據類型。

select * from E_Tab e 
    left outer join P_Tab p 
    on e.E_No= to_number (trim (p.P_No)) ; 
+0

'e。E_No = to_number(trim(p.P_No))'這部分正在工作。但是我沒有在不匹配的列中得到空值的預期輸出。 –

+0

'SELECT * FROM DUAL WHERE CAST('170'AS VARCHAR2(10))= 170;'將返回一行。 Oracle應該對'NUMBER'執行隱式類型轉換,並且前導和尾隨空格將被忽略。 – MT0