为什么Left Outer Join不能用于SQL中表中不同类型的属性?

时间:2017-08-24 09:29:34

标签: sql oracle

我有两张桌子。

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
对困惑感到抱歉。我的查询可能不正确。

3 个答案:

答案 0 :(得分:3)

  

" E_No在Number中,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)) ;

答案 1 :(得分: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

判例回答

如果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 |
+--+------+--------+---------+---------+--------+---------+

答案 2 :(得分:0)

如果一列的数据类型为CHAR,那么它将右边填充空格以填充列的大小。

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

根据Oracle的空白填充比较语义,返回零行'9''9 '不相等。

blank-padded comparison semantics州的文件:

  

使用空白填充语义,如果两个值具有不同的长度,则Oracle首先将空白添加到较短值的末尾,因此它们的长度相等。然后,Oracle将逐个字符的值与不同的第一个字符进行比较。在第一个不同位置具有较大字符的值被认为更大。如果两个值没有不同的字符,那么它们被认为是相等的。此规则意味着如果两个值仅在尾随空白的数量上不同,则它们是相等的。仅当比较中的两个值都是数据类型 CHAR NCHAR ,文本文字或值的表达式时,Oracle才使用空白填充比较语义由 USER 函数返回。

在上面的示例中,比较的左侧是VARCHAR(10),右侧是CHAR(10),然后不使用空白填充的比较语义。

<强>更新

  

E_No在Number中,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

将全部返回一行。