How to join two tables based on substring values of fields?

倾然丶 夕夏残阳落幕 提交于 2019-12-04 09:49:48

So many ways to do this. It would be a good idea to look at the explain plan for various ways before committing to a particular method. For example, if there is a function-based index on EMPLOYEE such as SUBSTR(id, 2, LENGTH(id) - 1) then you'll want to use that in your query:

SELECT e.name, i.name
  FROM employee e INNER JOIN instructor i
    ON SUBSTR(e.id, 2, LENGTH(e.id) - 1) = SUBSTR(i.id, 2, LENGTH(i.id) - 1);

Another question is if the values in the id column are always the same length in EMPLOYEE and INSTRUCTOR. What if they are of differing lengths? Maybe one has more padding than another. Also, will they always be digits apart from a leading u? If so, then it might be worthwhile to try a safe TO_NUMBER() conversion:

SELECT e.name, i.name
  FROM employee e INNER JOIN instructor i
    ON TO_NUMBER(REGEXP_SUBSTR(e.id, '\d+$')) = TO_NUMBER(REGEXP_SUBSTR(i.id, '\d+$'));

One other thing you may want to consider, however -- is there a reason for the leading u in the EMPLOYEE id column? Can there be other leading characters? Does the leading u stand for something (violating first normal form, but that happens)?

Oracle uses 1 as the base of its indexes, so substr('aaa',1,3) is equivalent to 'aaa'. You need to use 2 as the second parameter of substr in order to accomplish what you're attempting.


Beyond that, you'd probably be better off only changing one side, if you can. If the prefix characters are consistent, you could do this:

SELECT e.name, i.name
FROM   employee e INNER JOIN instructor i ON REPLACE (e.id, 'u', '0') = i.id

This would potentially allow the database to use an index on instructor, which would not be possible with your solution.

Santiago P

The character position is wrong. You should start your substring on the position 2 (the first character of your string is 1 and not 0). On the other side, you are using the SUBSTR function on both string while you should use only on the employee id. Be careful, if both ids are strings, the length will be different.

If you just only want to change the 'u' on the employee id, try with the TRANSLATE function.

TRANSLATE returns char with all occurrences of each character in from_string replaced by its corresponding character in to_string. Characters in char that are not in from_string are not replaced. The argument from_string can contain more characters than to_string. In this case, the extra characters at the end of from_string have no corresponding characters in to_string. If these extra characters appear in char, they are removed from the return value.

Syntax

──TRANSLATE──('char' , 'from_string' , 'to_string')──><

Pl/SQL Example
TRANSLATE ('abcd', 'ab', '12') ==> '12cd'
TRANSLATE ('12345', '15', 'xx') ==> 'x234x'
select e.name, i.name
 from  Employee e
 inner join Instructor i on SUBSTR(e.id, 2, LENGTH(e.id) - 1) = SUBSTR(i.id, 2, LENGTH(i.id) - 1)

Your DB uses 1-based indexing.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!