简体   繁体   English

Oracle SQL比较表中的记录

[英]Oracle SQL compare records within a table

I have a table like below: 我有一个如下表:

S.No | Item_ID | Item_Revision | Code |
-----+---------+---------------+-------
1.   | item1   | 0             | xyz  |
2.   | item2   | 0             | xyz  |
3.   | item3   | 0             | xyz  |
4.   | item1   | 1             |      |
5.   | item2   | 1             | abc  |
6.   | item3   | 1             | xyz  |

I need to compare the records in the table to find the differences in code in different revisions of the items. 我需要比较表中的记录,以找到不同版本的项目中的代码差异。

I want the result set as below: 我想要如下结果集:

 | Item_ID | Code_Revision_0 | Code_Revision_1 |
 | item1   | xyz             |                 |
 | item2   | xyz             | abc             |

I am not able to formulate an oracle query for this purpose. 我无法为此目的制定一个oracle查询。

Thanks in advance! 提前致谢!

You can use a self join to do this. 您可以使用自我联接来执行此操作。

select t1.item_id, t1.code code_rev_0, t2.code code_rev_1
from tablename t1
join tablename t2 on t1.item_id=t2.item_id 
and t1.item_revision = 0 and t2.item_revision = 1
where nvl(t1.code,'a') <> nvl(t2.code,'a')

One basic idea is to use join : 一个基本的想法是使用join

select t0.item_id, t0.code as code_0, t1.code as code_1
from t t0 join
     t t1
     on t0.item_id = t1.item_id and
        t0.item_revision = 0 and
        t1.item_revision = 1
where t0.code <> t1.code;

However, if the code value is NULL (or an empty string), you need to be more careful: 但是,如果code值为NULL (或空字符串),则需要格外小心:

where t0.code <> t1.code or (t0.code is null and t1.code is not null) or
      (t0.code is not null and t1.code is null) 

Here is a solution that uses the PIVOT operator instead of a self-join. 这是使用PIVOT运算符而不是自联接的解决方案。 If I am reading the execution plans correctly, this is slightly more efficient (cost of 13 vs. 17 for the join solution) for the input data you provided. 如果我正确地阅读了执行计划,那么对于您提供的输入数据,效率会稍高一些(连接解决方​​案的成本为13比17)。 You may want to test the two solutions on your actual data to see which works better. 您可能需要在实际数据上测试这两种解决方案,以查看哪种方法更好。

with
     input_data ( item_id, item_revision, code ) as (
       select 'item1', 0, 'xyz' from dual union all
       select 'item2', 0, 'xyz' from dual union all
       select 'item3', 0, 'xyz' from dual union all
       select 'item1', 1, ''    from dual union all
       select 'item2', 1, 'abc' from dual union all
       select 'item3', 1, 'xyz' from dual
     )
select *
from input_data
pivot (max(code) for item_revision in (0 as code_revision_0, 1 as code_revision_1))
where code_revision_0              != code_revision_1 
   or code_revision_0 is     null and code_revision_1 is not null
   or code_revision_0 is not null and code_revision_1 is     null
;

OUTPUT : 输出

ITEM_ CODE_REVISION_0  CODE_REVISION_1
----- ---------------- ----------------
item1 xyz
item2 xyz              abc

2 rows selected.

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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