简体   繁体   中英

Compare SQL rows in same table and print out when there are differences

I have a table

userid | name |      email       |  address 
-------+------+------------------+-----------
1      | joe  |  joe@gmail.com   |  123 Road 
1      | joe  |  joe@gmail.com   |  null
1      | joe  |     null         |  null 

I want to return a row for each time the user has been changed and which row was changed. So

Userid  |   change   
--------+-----------
  1     |   added address
  1     |   added email

If two things were changed at once, I want the 'Change' column to include both.

Currently I am doing something like this

SELECT 
   CASE WHEN table1.email <> table2.email THEN 'Email Change'
        WHEN table1.email IS NULL AND table2.email IS NOT NULL THEN 'Email addition' 
END email,
CASE WHEN table1.address <> table2.address THEN 'Address Change'
        WHEN table1.address IS NULL AND table2.address IS NOT NULL THEN 'Address addition' 
END address
FROM usertable table1 JOIN usertable table2 ON table1.userid = table2.userid

And comparing each column. Then I will concatenate email and address in another select for display.

Was wondering if there is anything more efficient since I will be comparing a good amount of columns. Could LAG be applied here?

I cannot use SP or any type of loop due to restrictions of system. using oracle. Any ideas here?

Thanks in advance!

Here's how I would do this. (The OP has his answer already, but perhaps this will help future readers.) It seems a lot better to have the information in separate columns for each attribute - then they can be concatenated if really needed for reporting purposes. The format I show before is more flexible - it allows to see how many name changes a user had, vs. how many email changes.

with
     base_table ( userid, eff_dt, name, email, address ) as (
       select 1, date '2015-10-22', 'joe', 'joe@gmail.com', '123 Road' from dual union all
       select 1, date '2016-03-20', 'joe', 'joe@gmail.com', null       from dual union all
       select 1, date '2016-09-01', 'joe', null           , null       from dual
     )
select userid, eff_dt, name, email, address,
       case when lag(name) over (partition by userid order by eff_dt) is null
                 and name is not null then 'added'
            when lag(name) over (partition by userid order by eff_dt) is not null
                 and name is null     then 'deleted'
            when lag(name) over (partition by userid order by eff_dt) != name
                                      then 'updated'              end as name_changes,
       case when lag(email) over (partition by userid order by eff_dt) is null
                 and email is not null then 'added'
            when lag(email) over (partition by userid order by eff_dt) is not null
                 and email is null     then 'deleted'
            when lag(email) over (partition by userid order by eff_dt) != email
                                       then 'updated'             end as email_changes,
       case when lag(address) over (partition by userid order by eff_dt) is null
                 and address is not null then 'added'
            when lag(address) over (partition by userid order by eff_dt) is not null
                 and address is null     then 'deleted'
            when lag(address) over (partition by userid order by eff_dt) != address
                                         then 'update             end as address_changes
from   base_table
;

Output :

USERID EFF_DT     NAME EMAIL         ADDRESS  NAME_CHANGES EMAIL_CHANGES ADDRESS_CHANGES
------ ---------- ---- ------------- -------- ------------ ------------- ---------------
     1 2015-10-22 joe  joe@gmail.com 123 Road added        added         added
     1 2016-03-20 joe  joe@gmail.com                                     deleted
     1 2016-09-01 joe                                      deleted

 3 rows selected.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM