Skip to Main Content
  • Questions
  • Use case statements to compare two columns

Breadcrumb

Question and Answer

Connor McDonald

Thanks for the question.

Asked: April 21, 2017 - 10:23 pm UTC

Last updated: April 26, 2017 - 4:15 am UTC

Version: Oracle 12c

Viewed 10K+ times! This question is

You Asked

Hi Tom,

Can you please suggest the best way to use case statements while comparing fields between two tables.

create table t1(id number, first_name varchar2(20), last_name varchar2(20), birth_date date);

insert into t1 (id, first_name, last_name, birth_date) values (1, 'John', 'Walker', '19500101');
insert into t1 (id, first_name, last_name, birth_date) values (2, 'Haley', 'Grant-Boon', '19510101');
insert into t1 (id, first_name, last_name, birth_date) values (3, 'Nikki', 'Alaska Santa', '19530101');
insert into t1 (id, first_name, last_name, birth_date) values (4, 'Jimmy', 'Cole Haan', '19540101');
insert into t1 (id, first_name, last_name, birth_date) values (5, 'Neil', 'O''Brian', '19550101'); ----- The last_name is O'Brian. I used two quotes to enable successful insert.

create table t2(id number, first_name varchar2(20), last_name varchar2(20), birth_date date);

insert into t2 (id, first_name, last_name, birth_date) values (1, 'John', 'Walker', '19500101');
insert into t2 (id, first_name, last_name, birth_date) values (2, 'Haley', 'Grant Boon', '19510101');
insert into t2 (id, first_name, last_name, birth_date) values (3, 'Nikki', 'Alaska Santa', '19530101');
insert into t2 (id, first_name, last_name, birth_date) values (4, 'Jimmy', 'Cole-Haan', '19540101');
insert into t1 (id, first_name, last_name, birth_date) values (4, 'Neil', 'OBrian', '19550101');


select t1.id, t1.first_name, t1.last_name
,t2.id, t2.first_name, t2.last_name
from t1, t2
where t1.birth_date = t2.birth_date
and t1.id = t2.id
----
---- FirstName Check logic
----
AND (CASE
WHEN REGEXP_INSTR (SUBSTR (t1.first_name, 1, 10),'[([:blank:]-,*_'')+]') > 0 THEN
SUBSTR (SUBSTR (t1.first_name, 1, 10), 1, REGEXP_INSTR (SUBSTR (t1.first_name, 1, 10), '[([:blank:]-,*_'')+]') - 1)
ELSE
SUBSTR (t1.first_name, 1, 10)
END) = (CASE
WHEN REGEXP_INSTR (substr(t2.First_Name,1,10), '[([:blank:]-,*_'')+]') > 0 THEN
SUBSTR (substr(t2.First_Name,1,10),1,REGEXP_INSTR (substr(t2.First_Name,1,10),'[([:blank:]-,*_'')+]')- 1)
ELSE
substr(t2.First_Name,1,10)
END)
-----------------------------------
---- LastName Check logic
-----------------------------------
AND (CASE
WHEN REGEXP_INSTR (SUBSTR (t1.last_name, 1, 14),'[([:blank:]-,*_)+]') > 0 THEN
SUBSTR (SUBSTR (t1.last_name, 1, 14), 1, REGEXP_INSTR (SUBSTR (t1.last_name, 1, 14),'[([:blank:]-,*_)+]')- 1)
ELSE
SUBSTR (t1.last_name, 1, 14)
END) = (CASE
WHEN REGEXP_INSTR (substr(t2.Last_Name,1,14),'[([:blank:]-,*_)+]') > 0 THEN
SUBSTR (substr(t2.Last_Name,1,14), 1,REGEXP_INSTR (substr(t2.Last_Name,1,14),'[([:blank:]-,*_)+]') - 1)
ELSE
substr(t2.Last_Name,1,14)
END)
)

Can you please help me with the above query. Is it efficient to use case statement for comparing the values.

We would like to compare the names i.e OBrian = O'Brian. and Cole-Haan = Cole Haan. In these cases the record should return true.

Thanks

and Connor said...

You could possibly use the UTL_MATCH functions, in conjunction with a regexp which retains only the alpha chars, eg


SQL> create table t1(id number, first_name varchar2(20), last_name varchar2(20), birth_date varchar2(20));

Table created.

SQL>
SQL> insert into t1 (id, first_name, last_name, birth_date) values (1, 'John', 'Walker', '19500101');

1 row created.

SQL> insert into t1 (id, first_name, last_name, birth_date) values (2, 'Haley', 'Grant-Boon', '19510101');

1 row created.

SQL> insert into t1 (id, first_name, last_name, birth_date) values (3, 'Nikki', 'Alaska Santa', '19530101');

1 row created.

SQL> insert into t1 (id, first_name, last_name, birth_date) values (4, 'Jimmy', 'Cole Haan', '19540101');

1 row created.

SQL> insert into t1 (id, first_name, last_name, birth_date) values (5, 'Neil', 'O''Brian', '19550101');

1 row created.

SQL>
SQL> create table t2(id number, first_name varchar2(20), last_name varchar2(20), birth_date varchar2(20));

Table created.

SQL> insert into t2 (id, first_name, last_name, birth_date) values (1, 'John', 'Walker', '19500101');

1 row created.

SQL> insert into t2 (id, first_name, last_name, birth_date) values (2, 'Haley', 'Grant Boon', '19510101');

1 row created.

SQL> insert into t2 (id, first_name, last_name, birth_date) values (3, 'Nikki', 'Alaska Santa', '19530101');

1 row created.

SQL> insert into t2 (id, first_name, last_name, birth_date) values (4, 'Jimmy', 'Cole-Haan', '19540101');

1 row created.

SQL> insert into t2 (id, first_name, last_name, birth_date) values (5, 'Neil', 'OBrian', '19550101');

1 row created.

SQL>
SQL> with t1x as
  2    ( select id,
  3             lower(regexp_replace(last_name,'[^[:alpha:]]*')) last_name,
  4             lower(regexp_replace(first_name,'[^[:alpha:]]*')) first_name,
  5             birth_date
  6      from   t1 ),
  7   t2x as
  8    ( select id,
  9             lower(regexp_replace(last_name,'[^[:alpha:]]*')) last_name,
 10             lower(regexp_replace(first_name,'[^[:alpha:]]*')) first_name,
 11             birth_date
 12      from   t2 )
 13  select
 14    t1.id,
 15    case
 16      when t1.last_name = t2.last_name and t1.first_name = t2.first_name then
 17            'BOTH CHAR MATCH'
 18      when  ( t1.last_name = t2.last_name and utl_match.edit_distance(t1.first_name,t2.first_name) <= 2  ) or
 19            ( t1.first_name = t2.first_name and utl_match.edit_distance(t1.last_name,t2.last_name) <= 2  ) then
 20            'ONE NAME MATCH, CLOSE ON OTHER'
 21      when  t1.last_name = t2.last_name or t1.first_name = t2.first_name then
 22            'ONE NAME MATCH'
 23    end matching
 24  from t1x t1, t2x t2
 25  where t1.birth_date = t2.birth_date
 26  and t1.id = t2.id;

        ID MATCHING
---------- ------------------------------
         1 BOTH CHAR MATCH
         2 BOTH CHAR MATCH
         3 BOTH CHAR MATCH
         4 BOTH CHAR MATCH
         5 BOTH CHAR MATCH

5 rows selected.

SQL>


Rating

  (1 rating)

Is this answer out of date? If it is, please let us know via a Comment

Comments

RE

GJ, April 24, 2017 - 12:00 pm UTC

THe soundex function gets you similar sounding comparison which works for O'Brian and Cole-Haan
select * 
 from t1 a
 join t2 b
   on a.id=b.id
where soundex(a.first_name||a.last_name)=soundex(b.first_name||b.last_name)


ID FIRST_NAME LAST_NAME BIRTH_DATE ID FIRST_NAME LAST_NAME BIRTH_DATE
1 John Walker 19500101 1 John Walker 19500101
2 Haley Grant-Boon 19510101 2 Haley Grant Boon 19510101
3 Nikki Alaska Santa 19530101 3 Nikki Alaska Santa 19530101
4 Jimmy Cole Haan 19540101 4 Jimmy Cole-Haan 19540101

Connor McDonald
April 26, 2017 - 4:15 am UTC

Nice input.