在Oracle中删除或添加前导0以匹配另一个值

问题描述

我在该网站上发现了许多与我的问题相关的类似问题,但是我找不到确切问题的答案。我要在控件编号上将表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上创建基于函数的索引。

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...