问题描述
我在该网站上发现了许多与我的问题相关的类似问题,但是我找不到确切问题的答案。我要在控件编号上将表A加入表B。表A的某些控制编号为6位,其他的控制编号为7位。表B仅具有7位。
Table A Table B
0000714 0000714
285073 0285073
我尝试做一个ltrim:
select ltrim(control_number,'0000000') as control_number from Table B
但是,不管控制编号中有多少位,这都会删除前导0。诸如012345之类的值将变为12345。
我只需要一个可以匹配两个表中控制编号的查询。
select a.*,b.*
from Table A
inner join Table B
on a.control_number = b.control_number
解决方法
由于您说过转换时遇到问题,您可以尝试将TRIM函数的扩展功能设为-
SELECT a.*,b.*
FROM Table_A
INNER JOIN Table_B ON TRIM(LEADING '0' FROM a.control_number) = TRIM(LEADING '0' FROM b.control_number)
,
如果您不关心性能,则可以将两者都转换为数字:
on to_number(a.control_number) = to_number(b.control_number)
如果您确实关心性能,请修正数据,使值具有相同的格式。此外,在应该声明表的表之间声明外键关系。
,您可以使用cast()
将其转换为整数,如下所示-
select a.*,b.*
from Table A
inner join Table B
on cast(a.control_number as int) = cast(b.control_number as int)
,
如果在尝试将列强制转换为数字时收到 ORA-01722:无效数字错误,则问题可能出在该列中的值不是数字。
使用类似以下查询的查询,可以根据需要将表连接起来。根据您的Oracle版本,您可能还可以使用VALIDATE_CONVERSION函数来帮助进行连接。
WITH
a (control_number)
AS
(SELECT '0000714' FROM DUAL
UNION ALL
SELECT '285073' FROM DUAL),b (control_number)
AS
(SELECT '0000714' FROM DUAL
UNION ALL
SELECT '0285073' FROM DUAL)
SELECT a.*,b.*
FROM a
INNER JOIN b
ON (CASE
WHEN LENGTH (a.control_number) < 7 THEN LPAD (a.control_number,7,'0')
ELSE a.control_number
END =
b.control_number);
,
使用零将表A中的值保留为7个字符。
select a.*,b.*
from Table A
inner join Table B
on lpad(a.control_number,'0') = b.control_number;
如果控制编号并非始终为数字,则可以避免出现ORA-01722
错误。
如果需要提高性能(例如,如果表A很大而表B很小),则使用查询中的lpad
表达式在表A上创建基于函数的索引。