2016-08-02 20 views
0

Ich habe eine Tabelle wie folgt:Oracle SQL vergleichen Datensätze innerhalb einer Tabelle

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 | 

Ich brauche die Datensätze in der Tabelle zu vergleichen, um die Unterschiede in Code in verschiedenen Revisionen der Elemente zu finden.

Ich mag das Ergebnis wie im Folgenden beschrieben:

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

Ich bin nicht in der Lage ein Orakel Abfrage für diesen Zweck zu formulieren.

Vielen Dank im Voraus!

Antwort

1

Eine Grundidee ist join zu verwenden:

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; 

Wenn jedoch der code Wert NULL (oder eine leere Zeichenkette), müssen Sie vorsichtiger sein:

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) 
+0

Ich markiere dies als eine Antwort, obwohl ich die Abfrage von Vkp verwende. weil deine Erklärung mich dazu gebracht hat, die Anfrage von vkp zu verstehen. Danke! –

1

Sie können einen Self-Join verwenden, um dies zu tun.

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') 
+1

Der Trick NVL in der 'where' Klausel am besten vermieden wird. Neben dem offensichtlichen ("a" kann ein legitimer Wert in der Spalte "code" sein), verbirgt dieser Trick die Absicht - wenn ein anderer Datenbankprofi den Code in Zukunft pflegen oder ändern muss, wird es viel einfacher für sie zu verstehen sein der Code (und vielleicht ändern Sie es, wenn nötig), wenn es vollständig ausgeschrieben ist, wie Gordon getan hat. (Ich habe das auch in meiner Lösung gemacht, aber Gordon hat den richtigen Weg gezeigt, dies vor mir zu tun.) Prost! – mathguy

1

Hier ist eine Lösung, die den PIVOT-Operator anstelle eines Self-Joins verwendet. Wenn ich die Ausführungspläne richtig lese, ist dies etwas effizienter (Kosten von 13 gegenüber 17 für die Join-Lösung) für die von Ihnen bereitgestellten Eingabedaten. Vielleicht möchten Sie die beiden Lösungen auf Ihren tatsächlichen Daten testen, um zu sehen, welche besser funktioniert.

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. 
Verwandte Themen