Nach zwei Werten einer Tabelle in einer anderen Tabelle prüfen

IchHH

Datenbank-Guru
Beiträge
282
Hallo,

heute habe ich eine Frage bevor ich eine nach eurer Ansicht "komische" Abfrage bastle.

Ich überlege wie ich es am besten anstelle nach zwei Werte einer Tabelle in einer anderen Tabelle auf Existenz zu prüfen.
Im Detail: Wenn ich z.B. einen Kundendatensatz haben der sich aus Ort, PLZ und Straße zusammensetzt und ich eine Datenbank haben in der alle Straße, Ort und PLZ aus Deutschland vorhanden sind, so müsste ich zwei wenn nicht sogar drei Prüfung vornehmen um festzustellen ob die Daten stimmen.

1. Passen PLZ und Ort zusammen
2. Passen Ort und Straße zusammen
3. Passen PLZ und Straße zusammen

Mir fällt es schwer hier einen Ansatz zu finden. Da ich mehrere Felder pro Zeile abgleichen muss.

Wie gehe ich da am besten ran?
 
Werbung:
vielleicht so:

Code:
test=*# select * from demo_table ;
 id | a  | b  | c  
----+----+----+----
  1 | 10 | 11 | 12
  2 | 10 | 11 | 13
  3 | 10 | 12 | 12
(3 Zeilen)

test=*# SELECT id ,sum(case when a=10 then 1 else 0 end + case when b=11 then 1 else 0 end + case when c = 12 then 1 else 0 end) as treffer from demo_table group by id having sum(case when a=10 then 1 else 0 end + case when b=11 then 1 else 0 end + case when c = 12 then 1 else 0 end) >= 2;
 id | treffer
----+---------
  1 |  3
  3 |  2
  2 |  2
(3 Zeilen)


Das an Deine Tabelle anzupassen überlasse ich Dir zur Übung.
 
Wiso nicht mit einem schnöden Join?
Code:
SELECT t1.pk AS nicht_existente_adresse FROM adressen_gegeben t1 LEFT JOIN alle_adressen t2 ON t1.pkz = t2.plz AND t1.ort = t2.ort AND t1.strasse = t2.strasse WHERE t2.pk IS NULL
 
Wenn du schon eine DB mit allen Orten und Straßen hast, wieso nutzt du dann nicht diese sondern speicherst Daten doppelt ab und vergleichst dann?
 
Das ist ganz einfach. Zum einen gibt es bei den Adresse sogenannte Adresszusätze zum anderen ist die Liste mit allen Orten und Straße vom Q1 diesen Jahres und inzwischen sind scheinbar neue Orte und Straße hinzugekommen und man darf nicht vergessen, dass ich die Liste nicht nutzen kann wenn sich nicht eindeutig identifizieren lässt ob es sich um die Adresse handelt oder wie würdest du das sonst sicherstellen? Ich habe die Erfahrung gemacht das entweder die PLZ stimmt der Ort aber nicht oder der Ort stimmt die PLZ aber nicht. Abgleichen kann man das wiederum aber nur wenn man die Straße mit einbezieht.

Ich versuche gerade den Ansatz von Ukulele umzusetzen um zu schauen ob ich damit meinem Ziel näher komme.

Ansätze von dir sind auch willkommen.
 
pk = primay key

In dem Join wird hat geguckt ob ein Treffer in den vorhandenen Adressen existiert und es werden nur die Datensätze angezeigt, wo das nicht so ist. Natürlich kann man das verfeinern, die Frage ist was raus kommen soll: Einfach nur die Datensätze die keinen exakten Match haben (so wäre es in diesem Fall) oder willst du auch Abweichungen anzeigen (also dein Beispiel PLZ identisch, Ort falsch)? Soll das dann alles in einem Datensatz pro Adresse zurück gegeben werden oder in mehreren? Wenn es die PLZ gibt aber nicht den Ort dann kann ja auch der Ort richtig und die PLZ falsch sein.
 
Du hast genau die Probleme angesprochen die ich habe. Bezogen auf die Postleitzahl und den Ort. Ich hatte gehofft das ich schaue ob es den Ort gibt, gibt es den Ort soll geprüft werden ob die PLZ korrekt ist. Eines beiden ist definitiv nicht richtig. Das konnte ich im Vorfeld schon filtern. Wenn aber die PLZ richtig ist, gibt es evtl. mehrere Orte die dazu passen, weshalb ich dann auf die Straße zurückgreifen wollte um die richtige ermitteln zu lassen. Am ende sollen also alle Datensätze angezeigt werden. Natürlich mit den richtigen Ort bzw. Postleitzahl.
 
Möglich wäre sowas hier:
Code:
WITH adressen(plz,ort,strasse) AS (
   SELECT '01234','Musterstadt','Musterstraße'
   ), test(id,plz,ort,strasse) AS (
   SELECT 1,'01234','Musterstadt','Musterstraße' UNION ALL
   SELECT 2,'01235','Musterstadt','Musterstraße' UNION ALL
   SELECT 3,'01234','Musterdorf','Musterstraße' UNION ALL
   SELECT 4,'01234','Musterstadt','Musterallee' UNION ALL
   SELECT 5,'01234','Musterdorf','Musterallee'
   )
SELECT   t.*,
     (   CASE
       WHEN   a1.plz IS NOT NULL
       THEN   'Adresse erkannt'
       WHEN   a2.plz IS NOT NULL
       THEN   'Vorschlag Straße: ' + a2.strasse
       WHEN   a3.plz IS NOT NULL
       THEN   'Vorschlag PLZ: ' + a3.plz
       WHEN   a4.plz IS NOT NULL
       THEN   'Vorschlag Ort: ' + a4.ort
       ELSE   'kein Vorschlag möglich'
       END ) AS meldung
FROM   test t
LEFT JOIN adressen a1
ON     t.plz = a1.plz
AND     t.ort = a1.ort
AND     t.strasse = a1.strasse
LEFT JOIN adressen a2
ON     t.plz = a2.plz
AND     t.ort = a2.ort
AND     t.strasse != a2.strasse
LEFT JOIN adressen a3
ON     t.ort = a3.ort
AND     t.strasse = a3.strasse
AND     t.plz != a3.plz
LEFT JOIN adressen a4
ON     t.strasse = a4.strasse
AND     t.plz = a4.plz
AND     t.ort != a4.ort
Das ganze ist noch nicht sehr elegant und wird an Grenzen stoßen. Ich würde für die Straße keine Vorschläge liefern. Die Vorschläge müssten auch noch aggregiert werden oder irgendwie sinnvoll vom in der UI angezeigt werden.
 
Ehrlich! Das ist weit über mein Wissen hinaus, was SQL angeht. Da es sich hier um mehrere tausende Datensätze geht stimme ich dir aber zu das eine manuelle Eingabe nicht sinnvoll ist.
 
Was hältst du von von dieser Lösungsansatz?

Code:
,    Case When v_plz & ' ' & Ort = PLZ & ' ' & Ortsteil then plz Case When [S_92634_1].[v_ort] & ' ' & left(Anschrift_Straße,3) = v_Ort & ' ' & left(Straße,3) then PLZ else 'fehler' End End as PLZ
,    Case When [S_92634_1].[v_ort] = [S_92576_1].[Ortsteil] Then [S_92576_1].[Ortsname] Else Case When left([S_92634_1].[Anschrift_straße],3) = left([S_92576_1].[Straße],3) then [S_92576_1].[Ortsname] Else 'Fehler' End End as Ort

er funktioniert zwar noch nicht, aber wenn ich beide Tabellen über ein CrossJoin verbinden müsste das doch klappen oder?
 
Erste Fehler entdeckt:
So müsste es lauten:
Code:
,    Case When [S_92634_1].[v_plz] & ' ' & [S_92576_1].[Ortsname] = [S_92576_1].[PLZ] & ' ' & [S_92576_1].[Ortsteil] Then [S_92576_1].[PLZ] When [S_92634_1].[v_ort] & ' ' & Left([S_92634_1].[Anschrift_straße],3) = [S_92634_1].[v_ort] & ' ' & Left([S_92576_1].[Straße],3) Then [S_92576_1].[PLZ] Else 'fehler' End As [PLZ]
,    Case When [S_92634_1].[v_ort] = [S_92576_1].[Ortsteil] Then [S_92576_1].[Ortsname] When Left([S_92634_1].[Anschrift_straße]

Fehlt nur noch das Lösen des Problemes der Inkompatibilität von Varchar & varchar im "&" Operator.
 
Jemand eine Idee. Habe es schon mittels Convert und den Datentypen nvarchar, text & float versucht, ohne Erfolg.
 
Werbung:
Zurück
Oben