Zeilen vergleichen Oracle SQL

baeri

Erfahrenes Mitglied
Hallo,

ich habe eine Tabelle mit Kundendatensätzen...
die Datensätze haben ALLE Unterschiedliche KundenIDs und verschiedene Mandandan (im Schlimmsten Fall kann also ein Kunde bis zu 15 Mal vorhanden sein). <- ja ich weiß das hätte man Intelligenter lösen können, leider muss ich jetzt damit leben.

Code:
ID | Kundenname | MD1 | PTN | Straße  | Hausnummer | PLZ  | Letzteaenderung ...
1  | KundeA     | A   | 1   | Zuhause | 12         | 1234 | 1.1. ...
2  | KundeA     | C   | 1   | Zuhause | 12         | 1234 | 5.1. ...
3  | KundeB     | E   | 2   | Auchwo  | 4          | 1234 | 3.1. ...
4  | KundeB     | A   | 2   | Auch_wo | 4          | 1234 | 12.1. ...

über die PTN (Partnernummer), kann man die "Kunden" eindeutig verbinden. Ziel ist es die Datensätze zu vergleichen und Fehler zu finden.
Fehler können im Namen oder in der Adresse (Straße, Hausnummer, PLZ, und noch ein paar Felder) sein. Mandant, oder Letztes Änderungsdatum darf hierbei nicht berücksichtigt werden ... SOLL aber erhalten bleiben.

Am Ende hätte ich gerne eine Auswertung bei der z.B. eine neue Spalte erzeugt wird in welcher ein "x" steht für "mit allen Identisch"

Meine Idee war es einen "Hilfsabruf" zu machen...

Code:
SELECT A.* FROM MEINETABELLE A, ( SELECT * FROM MEINETABELLE WHERE PTN = A.PTN ) B
WHERE 1=1
AND A.Kundenname = B.Kundenname
AND ...

Aber da Verliesen mich meine konstruktiven Gedanken...

Wie stelle ich das "Intelligent" an? Ich muss da mich zwar schon durch 40000 Kundendatensätzen wühlen, das aber nur "einmal im Monat", daher muss ich Laufzeit nicht so 1000%tig performant sein... Hier geht es nur um einen Abgleich, ob die Daten passen...

Vielen vielen Dank
 
Nachtrag:
Ups, du willst es ja gar nicht so kompliziert. Du hast ja bereits eine Nummer um die zusammengehörigen zu finden.
Wie soll den deine Ausgabe aussehen?

Ich lasse meine andere Lösung mal stehen. sie ist zu schön um in Vergessenheit zu geraten

---
Am Ende muss immer jemand entscheiden, ob es derselbe ist. Du kannst Vorschläge erarbeiten.
Am besten mit einer Wertung. Du entscheidest, welche Feldübereinstimmung wie viele Wertepunke sind. zB. gleicher Kundennamen ist 5 Punkte, ähnlicher Kundennamen 3 Punkte. Gleicher Hausnummer 3, Gleicher Ort 4etc.
Dann suchst du Gemeinsamkeiten und zählst die Punkte zusammen.

Hier mal mit 3 Feldern, die ich prüfe

SQL:
select
  c.PKT_KUNDENNAME + c.PKT_MD1 + c.PKT_STRASSE as PUNKTE,
  c.*
from
  (
    select
      a.ID as ID_1,
      b.ID as ID_2,
      a.KUNDENNAME as KUNDENNAME_1,
      b.KUNDENNAME as KUNDENNAME_2,
      a.MD1 as MD1_1,
      b.MD1 as MD1_2,
      a.STRASSE as STRASSE_1,
      b.STRASSE as STRASSE_2,
      case
         -- Auf Gleichheit prüfen
        when a.KUNDENNAME = b.KUNDENNAME
        then 5
        -- Auf Ähnlichkeit prüfen http://www.dba-oracle.com/t_utl_match.htm
        when UTL_MATCH.EDIT_DISTANCE_SIMILARITY(a.KUNDENNAME, (b.KUNDENNAME)) > 80
        then 3
        else 0
      end as PKT_KUNDENNAME,
      case
        when a.MD1 = b.MD1
        then 2
        else 0
      end as PKT_MD1,
      case
        when a.STRASSE = b.STRASSE
        then 5
        when UTL_MATCH.EDIT_DISTANCE_SIMILARITY(a.STRASSE, (b.STRASSE)) > 80
        then 3
        else 0
      end as PKT_STRASSE
    from
      -- ID-Kombinationen, so dass jede Kombination nur einmal vorkommt
      (
        select distinct
          least(a.id, b.id) as aid,
          greatest(a.id, b.id) as bid
        from my_table a, my_table b
        where a.id <> b.id
      ) ids,
      my_table a,
      my_table b
    where
      ids.aid = a.id
      and ids.bid = b.id
  ) c
where
  -- Nur Einträge nehmen, die irgendein Treffer haben
  -- Man kannnatürlich auch eine Minimalpunktzahl setzen
  c.PKT_KUNDENNAME + c.PKT_MD1 + c.PKT_STRASSE > 0
order by
  (c.PKT_KUNDENNAME + c.PKT_MD1 + c.PKT_STRASSE) desc
;
gibt auf deine Testdaten folgendes
Code:
PUNKTE | ID_1 | ID_2 | KUNDENNAME_1 | KUNDENNAME_2 | MD1_1 | MD1_2 | STRASSE_1 | STRASSE_2 | PKT_KUNDENNAME | PKT_MD1 | PKT_STRASSE
-----------------------------------------------------------------------------------------------------------------------------------
    10 |    1 |    2 | KundeA       | KundeA        | A    | C     | Zuhause   | Zuhause   |              5 |       0 |           5
     8 |    3 |    4 | KundeB       | KundeB        | E    | A     | Auchwo    | Auch_wo   |              5 |       0 |           3
     5 |    1 |    4 | KundeA       | KundeB        | A    | A     | Zuhause   | Auch_wo   |              3 |       2 |           0
     3 |    2 |    3 | KundeA       | KundeB        | C    | E     | Zuhause   | Auchwo    |              3 |       0 |           0
     3 |    1 |    3 | KundeA       | KundeB        | A    | E     | Zuhause   | Auchwo    |              3 |       0 |           0
     3 |    2 |    4 | KundeA       | KundeB        | C    | A     | Zuhause   | Auch_wo   |              3 |       0 |           0
Man sieht jetzt sehr schön in der Ersten Spalte. Die erste Zeile hat 10 von 12 möglichen Punken. Die Chance ist also sehr gross, dass es derselbe Kunde ist.
Bei Zeile 2 sieht man, dass PKT_STRASSE 3 Punkte bekommen hat. Die zwei Strassen sind sich als sehr ähnlich

Je weiter Unten ein Vergleich, umso unwahrscheinlicher, dass die Daten zusammenpassen

Ach ja, schnell wird das nicht sein....
 
Zuletzt bearbeitet:
Hehe,

sehr schön... <- aber nicht ganz das "gesuchte"

genau gesagt will ich 2 Ausgaben...
einmal jene welche Differenzen haben

in meinem Beispiel (hier nur der Kunde sichtbar bei welchen die Straße anders geschrieben wurde):
Code:
3  | KundeB     | E   | 2   | Auchwo  | 4          | 1234 | 3.1. ...
4  | KundeB     | A   | 2   | Auch_wo | 4          | 1234 | 12.1. ...

eine einfache Liste mit den Datensätzen welche nicht übereinstimmen... ist nur 1 vorhanden oder sind die "Überprüfungsdaten" Identisch, will ich keine Ausgabe.

in der 2. Ausgabe will ich "am liebsten" eine Gruppe der IDs, Mandanten und Änderungsdatums ( ID: 1, 4, 12 | Name: KundeC | Mandant: A, A, C ) + ein Feld ob die Datensätze "überein" stimmen.
Das "führende" Feld soll das mit der "neusten Änderung" sein.

Code:
ID | Kundenname | MD1 | PTN | Straße  | Hausnummer | PLZ  | Letzteaenderung | Uebereinstimmung
1,2| KundeA     | A,C | 1   | Zuhause | 12         | 1234 | 5.1.            | X
3,4| KundeB     | E,A | 2   | Auch_wo | 4          | 1234 | 12.1.           | FALSCH

Vielen vielen Dank
 
SQL:
select distinct
  t1.*
from
  (
    -- Gruppieren nach PTN. Wenn der Count grösser als 1 ist, gibt es unstimmigkeiten
    select ptn, count(*) as cnt
    from (
      -- Gruppieren und zählen nach allen relevanten Feldern + PTN
        select ptn, count(*) as cnt
        from my_table t
        group by
          ptn, KUNDENNAME, STRASSE
      ) p1
    group by p1.ptn
    having count(*) > 1
  ) p2,
  my_table t1
where t1.ptn = p2.ptn
 

Neue Beiträge

Zurück