AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Datenbanken Zugriff auf eine n:m Verknüpfung
Thema durchsuchen
Ansicht
Themen-Optionen

Zugriff auf eine n:m Verknüpfung

Ein Thema von Luckner · begonnen am 31. Mär 2022 · letzter Beitrag vom 1. Apr 2022
Antwort Antwort
Seite 1 von 2  1 2      
Luckner

Registriert seit: 28. Nov 2006
Ort: Berlin
418 Beiträge
 
Delphi 7 Enterprise
 
#1

Zugriff auf eine n:m Verknüpfung

  Alt 31. Mär 2022, 13:01
Datenbank: Firebird • Version: 2.5 • Zugriff über: IBDataset
Hallo,
habe, möglicherweise, eine triviale Frage. in einer Datenbank habe ich ein 1. Kunden-Tabelle und 2. Lieferadressen-Tabelle. Die Kunden haben verschiedene Lieferadressen und es kommt vor, dass eine Lieferadresse mehreren Kunden zugerordnet werden muss. Habe deswegen eine 3. Tabelle mit ID, IDKUNDE, IDLIEFERADRESSEN erstellt. Wie macht man eine select-Abfrage, wenn man für einen Kunden die Lieferadressen filtern möchte. Mein Gedanke ist, dass über eine select-Anweisung mit where IDKUNDE = Zahl und in einer while-Schleife dann ein weiteres select mit where = entsprechende IDLIEFERADRESSEN. Aber ich kann mir jedoch vorstellen, dass es dafür eine schnellere Anweisung gibt. Möglicherweise irgendetwas mit JOIN.

Habe es folgendermassen versucht:

Delphi-Quellcode:
('SELECT * FROM KUNDENSTAMM ');
('JOIN KUNDENLIEFERADRESSEN ON ' + IntToStr(KundenID) + ' = KUNDENLIEFERADRESSEN.IDKUNDEN');
('JOIN ADRESSENSTAMM ON KUNDENLIEFERADRESSEN.IDADRESSEN = ADRESSENSTAMM.ID');
Es werden mit dem o.g. select-Aufruf die richtigen Lieferadressen für diesen Kunden angezeigt. Jedoch multipliziert mit der Anzahl der Kunden in der Kundentabelle. Also so: für Kunden Müller:
Berlin
Bremen
München
Köln
Berlin
Bremen
München
Köln
Berlin
Bremen
München
Köln

bei 3 Kunden in der Kundentabelle. Das Programm soll nur die Adressen des einen Kunden zeigen.
Was funktioniert, wenn ich aus der Verbindungstabelle über eine select-Anweisung mit einer Kundenentsprechenden_ID alle dazugehörigen Lieferadressen_ID's herausfiltere und dann mit einer While-Schleife und einer Select-Anweisung mit der aktl. Lieferadressen_ID die Daten aus der Lieferadressen-Tabelle heraussuche.

Danke, Luckner
  Mit Zitat antworten Zitat
Poelser

Registriert seit: 21. Apr 2008
Ort: Europa
145 Beiträge
 
Delphi 10.4 Sydney
 
#2

AW: Zugriff auf eine n:m Verknüpfung

  Alt 31. Mär 2022, 13:24
Moin,
Möglicherweise irgendetwas mit JOIN.

Habe es folgendermassen versucht:

Delphi-Quellcode:
('SELECT * FROM KUNDENSTAMM ');
('JOIN KUNDENLIEFERADRESSEN ON ' + IntToStr(KundenID) + ' = KUNDENLIEFERADRESSEN.IDKUNDEN');
('JOIN ADRESSENSTAMM ON KUNDENLIEFERADRESSEN.IDADRESSEN = ADRESSENSTAMM.ID');
Ganz sicher kannst du das mit JOIN, z.B.
SELECT * FROM KUNDENSTAMM k JOIN KUNDENLIEFERADRESSEN kla ON k.KundenID = kla.IDKUNDEN JOIN ADRESSENSTAMM a ON kla.IDADRESSEN = a.ID Und das dann noch mit WHERE k.ID = 1234 einschränken, damit du die Daten auch auf einen Kunden beschränken kannst.
Edit: Allerdings frage ich mich, ob du eine m:n-Beziehung brauchst - kann denn eine Lieferadresse mehr als einem Kunden gehören?
LG aus dem hohen Norden, Edmund

Geändert von Poelser (31. Mär 2022 um 13:28 Uhr) Grund: Noch Erklärung n:m eingebaut
  Mit Zitat antworten Zitat
Benutzerbild von Jasocul
Jasocul

Registriert seit: 22. Sep 2004
Ort: Delmenhorst
1.337 Beiträge
 
Delphi 11 Alexandria
 
#3

AW: Zugriff auf eine n:m Verknüpfung

  Alt 31. Mär 2022, 13:34
Einerseits denkst du viel zu kompliziert, andererseits zu einfach. Dazu kommt eine leichte Fehlkonstruktion der Tabellen.

Du kannst es dir im Moment noch einfach machen, da in den Kundenlieferadressen die kundenid noch enthalten ist. Du benötigst für die aktuelle Anforderung die dritte Tabelle (noch) nicht:
Code:
SELECT * FROM KUNDENSTAMM
JOIN KUNDENLIEFERADRESSEN ON KUNDENSTAMM.ID = KUNDENLIEFERADRESSEN.IDKUNDEN
WHERE KUNDENSTAMM.ID = <Deine Kunden-ID>
Wenn du die Fehlkunstruktion entfernst, ist es etwas "komplizierter".
Die Fehlkonstruktion ist die Kunden-ID in der Tabelle KUNDENLIEFERADRESSEN. Mit der n:m-Beziehung sollte das Feld dort eigentlich nicht mehr vorhanden sein.
Das entsprechende SQL-Statement sieht dann etwa so aus:
Code:
SELECT * FROM KUNDENSTAMM
JOIN ADRESSENSTAMM ON KUNDENSTAMM.ID = ADRESSENSTAMM.IDKUNDE
JOIN KUNDENLIEFERADRESSEN ON ADRESSENSTAMM.IDLIEFERADRESSEN = KUNDENLIEFERADRESSEN.ID
WHERE KUNDENSTAMM.ID = <Deine Kunden-ID>
Was dir eigentlich gefehlt hat, war die Where-Bedingung. BTW: Du solltest mit Parametern arbeiten und nicht die Werte direkt ins SQL einbauen. Aber das ist noch ein anderes Thema.

Es kann sein, dass die SQLs nicht ganz sauber sind, da ich die nicht kontrollieren kann und mir auch die IDs nicht alle genau bekannt sind. Könnte also sein, dass du noch ein bisschen nacharbeiten musst.
Peter

Geändert von Jasocul ( 1. Apr 2022 um 06:10 Uhr)
  Mit Zitat antworten Zitat
Luckner

Registriert seit: 28. Nov 2006
Ort: Berlin
418 Beiträge
 
Delphi 7 Enterprise
 
#4

AW: Zugriff auf eine n:m Verknüpfung

  Alt 31. Mär 2022, 15:46
Hallo Poelser,

ja eine Lieferadresse kann von mehreren Kunden benutzt werden. kannst Du bitte nocheinmal einen Blick auf Deine select-Anweisung werfen. Habe sie versucht umzusetzen, jedoch kommt nicht die richtigen Daten raus. Folgende Tabellen habe ich Tabelle KUNDENSTAMM mit dem Feld ID (also KUNDENSTAMM.ID), ADRESSENSTAMM mit dem Feld ID (also ADRESSENSTAMM.ID) und als 3.-tes KUNDENLIEFERADRESSEN mit den Felden IDKUNDEN und IDADRESSEN. Möglicherweise habe ich bei Deiner Anweisung einige ID's durcheinander gebracht.

Danke. Luckner
  Mit Zitat antworten Zitat
TigerLilly

Registriert seit: 24. Mai 2017
Ort: Wien, Österreich
1.174 Beiträge
 
Delphi 11 Alexandria
 
#5

AW: Zugriff auf eine n:m Verknüpfung

  Alt 31. Mär 2022, 16:05
Ohne Tabellenstruktur ist es schwer, einen brauchbaren Tipp zu geben.
Aber grundsätzlich solltest du die Adressen zu einem Kunden über JOIns bekommne:

Hol dir den Kunden:

select * from KUNDENSTAMM s
where s.ID=??

joine die m:n Tabelle dazu:

select * from KUNDENSTAMM s
join KUNDENLIEFERADRESSEN kl on s.ID=kl.IDKunden
where s.ID=??

jetzt noch die Adresse dazu

select * from KUNDENSTAMM s
join KUNDENLIEFERADRESSEN kl on s.ID=kl.IDKunden
join ADRESSENSTAMM a on a.ID = kl.IDADRESSEN
where s.ID=??

Wobei ich das Schema schwierig finde. Wenn sich die Adresse eines Kunden ändert, darf ich sie nicht ändern, sondern muß eine neue Adresse zuordnen. Aber das weißt du natürlich besser.
  Mit Zitat antworten Zitat
jobo

Registriert seit: 29. Nov 2010
3.072 Beiträge
 
Delphi 2010 Enterprise
 
#6

AW: Zugriff auf eine n:m Verknüpfung

  Alt 31. Mär 2022, 16:47
Leider ist mir nicht ganz klar, welche Tabelle welche ID Spaltennamen hat.
In solchen Selectstatements, gerade wenn man sie im Forum zeigt, ist es immer praktisch, alle Spalten mit Tabellen Alias anzugeben.

Hier ist ein Beispiel:
https://dbfiddle.uk/?rdbms=postgres_...b4ebe896462ccc

Die ID in der Tabelle adressenstamm ist je nach Geschmack überflüssig. Sie wird wohl als Primärschlüssel gedacht sein, einziger Anwendungsfall wäre aber das gezielte Löschen eines Datensatzes ohne dabei 2 Spalten zur Identifikation nutzen zu müssen.
Gruß, Jo
  Mit Zitat antworten Zitat
Benutzerbild von dataspider
dataspider

Registriert seit: 9. Nov 2003
Ort: 04539 Groitzsch
1.350 Beiträge
 
Delphi 11 Alexandria
 
#7

AW: Zugriff auf eine n:m Verknüpfung

  Alt 31. Mär 2022, 17:00
Hallo Poelser,

ja eine Lieferadresse kann von mehreren Kunden benutzt werden. kannst Du bitte nocheinmal einen Blick auf Deine select-Anweisung werfen. Habe sie versucht umzusetzen, jedoch kommt nicht die richtigen Daten raus. Folgende Tabellen habe ich Tabelle KUNDENSTAMM mit dem Feld ID (also KUNDENSTAMM.ID), ADRESSENSTAMM mit dem Feld ID (also ADRESSENSTAMM.ID) und als 3.-tes KUNDENLIEFERADRESSEN mit den Felden IDKUNDEN und IDADRESSEN. Möglicherweise habe ich bei Deiner Anweisung einige ID's durcheinander gebracht.

Danke. Luckner
Teste besser Peter seinen Vorschlag...
Das mit der ID im ON eines Joins ist schon speziell...

Frank
Frank Reim
  Mit Zitat antworten Zitat
Poelser

Registriert seit: 21. Apr 2008
Ort: Europa
145 Beiträge
 
Delphi 10.4 Sydney
 
#8

AW: Zugriff auf eine n:m Verknüpfung

  Alt 1. Apr 2022, 06:41
Moin,
select * from KUNDENSTAMM s
join KUNDENLIEFERADRESSEN kl on s.ID=kl.IDKunden
join ADRESSENSTAMM a on a.ID = kl.IDADRESSEN
where s.ID=??

Wobei ich das Schema schwierig finde. Wenn sich die Adresse eines Kunden ändert, darf ich sie nicht ändern, sondern muß eine neue Adresse zuordnen. Aber das weißt du natürlich besser.
So hatte ich das ja in etwa auch beschrieben. Sein Problem ist ja, dass eine Adresse mehreren Kunden gehören kann. Da ist schon eine m:n-Beziehung nötig.

Mit Blick auf den Datenverbrauch (Stichwort 1.-5. Normalform) ist das ja insofern richtig so, es wird nichts redundant gespeichert.

Aber es ist gerade deshalb ja schwierig, weil z.B. das Hinzufügen einer Adresse in 2 Tabellen stattfinden muss- > Adresse in ADRESSENSTAMM hinzufügen UND Zuordnung in KUNDENLIEFERADRESSEN.
LG aus dem hohen Norden, Edmund
  Mit Zitat antworten Zitat
Luckner

Registriert seit: 28. Nov 2006
Ort: Berlin
418 Beiträge
 
Delphi 7 Enterprise
 
#9

AW: Zugriff auf eine n:m Verknüpfung

  Alt 1. Apr 2022, 08:25
Guten Morgen an Alle,

dass mit dem Hinzufügen einer KUNDENLIEFERADRESSEN dürfte nicht so schwierig sein. Entweder ich bin in einem Datensatz eines Kunden und füge eine zusätzliche Lieferadresse ein, dann ist die ID des Kunden bekannt und in der Verknüpfungstabelle füge ich die Verknüpfung erst dann ein, nachdem ich den Eintrag in der Adressenstamm-Tabelle eingetragen habe. Dann mit Last in dieser Tabelle habe ich die letzte ID der Adressenstamm-Tabelle. Die Kombination der Kunden.ID und der Adressenstamm.ID trage ich in die Verkprüfungstabelle ein. Müsste funktionieren.

Gruß, Luckner
  Mit Zitat antworten Zitat
Poelser

Registriert seit: 21. Apr 2008
Ort: Europa
145 Beiträge
 
Delphi 10.4 Sydney
 
#10

AW: Zugriff auf eine n:m Verknüpfung

  Alt 1. Apr 2022, 08:45
Ich denke auch, dass das funktioniert, aaaber:

Bevor du eine Adresse hinzufügst, musst du erstmal prüfen, ob es die bereits in der Tabelle gibt. Wenn ja, brauchst du nur einen Eintrag in der Zwischentabelle anlegen.

Nur wenn die Adresse nicht existiert, sind eben 2 Schritte notwendig: Adresse hinzufügen und Verknüpfung mit dem Kundenstamm.
LG aus dem hohen Norden, Edmund
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 18:33 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz