Zugriff auf eine n:m Verknüpfung
-
- Beiträge: 88
- Registriert: Sa 18. Jan 2020, 09:56
- OS, Lazarus, FPC: Winux (L 2.2.0 FPC 3.2.2)
- CPU-Target: Windows 64-Bit
Zugriff auf eine n:m Verknüpfung
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.
Danke, Luckner
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.
Danke, Luckner
-
- Lazarusforum e. V.
- Beiträge: 370
- Registriert: So 5. Mai 2019, 16:52
- OS, Lazarus, FPC: ArchLinux und Windows mit FPCUPdeluxe (L: 3.6, FPC 3.2.2)
- CPU-Target: x86_64, i386
- Wohnort: Bayreuth
Re: Zugriff auf eine n:m Verknüpfung
Hi,
schon mal was von JOINS im SELECT gehört?
Schneller sollte es nicht gehen...
cu tb
schon mal was von JOINS im SELECT gehört?
Code: Alles auswählen
SELECT *
FROM kunden
LEFT JOIN verbindungstabelle ON idkunde = verbindungskundenid
LEFT JOIN lieferadresse ON verbindungslieferadressenid = lieferadressenid
cu tb
Tipp für PostgreSQL: www.pg-forum.de
Re: Zugriff auf eine n:m Verknüpfung
Kunde hat eine lfdnr
Lieferadressen haben eine lfdnr
Tabelle Kunde_Lieferadresse hat die Einträge: Kunde.lfdnr und Lieferadresse.lfdnr
...ohne Prüfung hingeschrieben, teste mal
Edit: Ich934 war schneller...
Lieferadressen haben eine lfdnr
Tabelle Kunde_Lieferadresse hat die Einträge: Kunde.lfdnr und Lieferadresse.lfdnr
Code: Alles auswählen
Query1.sql.text:=
'Select Lieferadresse.* from Kunde '+
' left join Kunde on Kunde.lfdnr=:KUNDE '+
' left join Kunde_Lieferadresse on Kunde_Lieferadresse.kunde=Kunde.lfdnr '+
' left join Lieferadresse on Lieferadresse.lfdnr=Kunde_Lieferadresse.Lieferadresse '+
'where Kunde.lfdnr=:KUNDE;';
Query1.Parambyname('KUNDE').asinteger:=KundeID;
Edit: Ich934 war schneller...
Gruß, Michael
-
- Beiträge: 1065
- Registriert: Sa 12. Sep 2015, 12:10
- OS, Lazarus, FPC: Laz stable (2.2.6, 3.x)
- CPU-Target: Win 32/64, Linux64
- Wohnort: Wien
Re: Zugriff auf eine n:m Verknüpfung
Wenn er die ID des Kunden schon weiß dann braucht es in dem SELECT keine Kundentabelle.
Wird in einer großen DB sicher schneller, auch wenn der DB-Optimizer sicher zuerst die Daten aus der Kundentabelle holt und die hoffentlich auf ID indiziert ist.
Und wenn das eine normale Abfrage der Lieferadressen eines Kunden sein soll, dann brauchts auch kein LEFT JOIN, denn wenn es keine Lieferadressen gibt, ist die Abfrage eben leer. LEFT JOIN würde dazu führen dass auch Kunden ohne Lieferadresse ausgegeben würden. Wenn es nur um die Lieferadressen geht reicht ein JOIN
Das reicht auch zur Anzeige in einem entsprechenden Grid oder einer Auswahlmöglichkeit.
Ich nehme jetzt einfach an dass SELECT * FROM nur exemplarisch gemeint war, denn den Hauptteil der Performance lässt man beim übertragen unnötiger Tabellenspalten liegen. Besonders im Zeitalter von HomeOffice ist die Datenmenge über langsame Verbindungen ein Thema.
-
- Beiträge: 88
- Registriert: Sa 18. Jan 2020, 09:56
- OS, Lazarus, FPC: Winux (L 2.2.0 FPC 3.2.2)
- CPU-Target: Windows 64-Bit
Re: Zugriff auf eine n:m Verknüpfung
Vielen Dank für die Hilfe,
habe jetzt den Vorschlag von Ich934, entsprechend angepasst, verwendet:
Es werden schon die richtigen Lieferadressen angezeigt, jedoch multipliziert mit der Anzahl der Kunden in der Kundentabelle. Also in der Kundentabelle gibt es 4 Kunden. Der Kunde "Meier = ID=1" hat 3 Einträge in der Verbindungstabelle 1:1, 1:3, 1:4, dann wird in der entprechendem Grid (verknüpft mit entsprechendem IBDatasource) 4x die Lieferadressen angezeigt. Den Rowcount habe ich auch ausgegeben und es kommt eine 11 raus. Also 12 Einträge. Auch bei wegnahme von 'LEFT' keine Änderung.
Gruß, Luckner
habe jetzt den Vorschlag von Ich934, entsprechend angepasst, verwendet:
Code: Alles auswählen
('SELECT * FROM KUNDENSTAMM ');
('JOIN KUNDENLIEFERADRESSEN ON ' + IntToStr(KundenID) + ' = KUNDENLIEFERADRESSEN.IDKUNDEN');
('JOIN ADRESSENSTAMM ON KUNDENLIEFERADRESSEN.IDADRESSEN = ADRESSENSTAMM.ID');
Gruß, Luckner
-
- Beiträge: 88
- Registriert: Sa 18. Jan 2020, 09:56
- OS, Lazarus, FPC: Winux (L 2.2.0 FPC 3.2.2)
- CPU-Target: Windows 64-Bit
Re: Zugriff auf eine n:m Verknüpfung
Nicht den Rowcount, sondern den Recordcount.
Luckner
Luckner
- af0815
- Lazarusforum e. V.
- Beiträge: 6791
- Registriert: So 7. Jan 2007, 10:20
- OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
- CPU-Target: 32Bit (64Bit)
- Wohnort: Burgenland
- Kontaktdaten:
Re: Zugriff auf eine n:m Verknüpfung
Die Frage ist immer, welche Informationen du anzeigen willst
Hier werden mal die Auswirkungen der verschiedenen Joins gezeigt
https://www.ionos.at/digitalguide/hosti ... uter-join/
Recordcount würde ich nicht verwenden, außer du kennst genau die Einschränkungen und Auswirkungen. Genaugenommen ist das ein FetchCount.

Hier werden mal die Auswirkungen der verschiedenen Joins gezeigt
https://www.ionos.at/digitalguide/hosti ... uter-join/
Recordcount würde ich nicht verwenden, außer du kennst genau die Einschränkungen und Auswirkungen. Genaugenommen ist das ein FetchCount.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).
-
- Beiträge: 88
- Registriert: Sa 18. Jan 2020, 09:56
- OS, Lazarus, FPC: Winux (L 2.2.0 FPC 3.2.2)
- CPU-Target: Windows 64-Bit
Re: Zugriff auf eine n:m Verknüpfung
Hallo af0815,
ich würde gerne in einem Grid die Lieferadressen eines Kunden anzeigen. Wobei versch. Kunden auch die gleichen Lieferadressen haben können.
Gruß, Luckner
ich würde gerne in einem Grid die Lieferadressen eines Kunden anzeigen. Wobei versch. Kunden auch die gleichen Lieferadressen haben können.
Gruß, Luckner
- af0815
- Lazarusforum e. V.
- Beiträge: 6791
- Registriert: So 7. Jan 2007, 10:20
- OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
- CPU-Target: 32Bit (64Bit)
- Wohnort: Burgenland
- Kontaktdaten:
Re: Zugriff auf eine n:m Verknüpfung
Meintest du sowas ? Oder habe ich da was falsch verstanden.
Ergebnis:
DB: MS-SQL free unter Ubuntu laufend, Verwaltet mit den normalen Microsoft SQL Server Managment Studio (SSMS) unter Windows 10/64
Code: Alles auswählen
SELECT dbo.X_Kunden.Name, dbo.X_Adr.Adresse
FROM dbo.X_MN_KundenAdr INNER JOIN
dbo.X_Adr ON dbo.X_MN_KundenAdr.AdrID = dbo.X_Adr.AdrID RIGHT OUTER JOIN
dbo.X_Kunden ON dbo.X_MN_KundenAdr.KundenID = dbo.X_Kunden.NameID
Das ist meine schnelle DemoDBName Adresse
Kunde1 Adresse 1
Kunde1 Adresse 2
Kunde2 Adresse 1
Kunde3 Adresse 3
Code: Alles auswählen
USE [Adressbuch]
GO
/****** Object: Table [dbo].[X_Kunden] Script Date: 31.03.2022 10:55:01 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[X_Kunden](
[NameID] [int] NOT NULL,
[Name] [nvarchar](50) NOT NULL
) ON [PRIMARY]
GO
/****** Object: Table [dbo].[X_Adr] Script Date: 31.03.2022 10:55:01 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[X_Adr](
[AdrID] [int] NOT NULL,
[Adresse] [nvarchar](50) NOT NULL
) ON [PRIMARY]
GO
/****** Object: Table [dbo].[X_MN_KundenAdr] Script Date: 31.03.2022 10:55:01 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[X_MN_KundenAdr](
[MNID] [int] NOT NULL,
[KundenID] [int] NOT NULL,
[AdrID] [int] NOT NULL
) ON [PRIMARY]
GO
/****** Object: View [dbo].[XV_KundenAdr] Script Date: 31.03.2022 10:55:01 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE VIEW [dbo].[XV_KundenAdr]
AS
SELECT dbo.X_Kunden.Name, dbo.X_Adr.Adresse
FROM dbo.X_MN_KundenAdr INNER JOIN
dbo.X_Adr ON dbo.X_MN_KundenAdr.AdrID = dbo.X_Adr.AdrID RIGHT OUTER JOIN
dbo.X_Kunden ON dbo.X_MN_KundenAdr.KundenID = dbo.X_Kunden.NameID
GO
INSERT [dbo].[X_Adr] ([AdrID], [Adresse]) VALUES (1, N'Adresse 1')
GO
INSERT [dbo].[X_Adr] ([AdrID], [Adresse]) VALUES (2, N'Adresse 2')
GO
INSERT [dbo].[X_Adr] ([AdrID], [Adresse]) VALUES (3, N'Adresse 3')
GO
INSERT [dbo].[X_Kunden] ([NameID], [Name]) VALUES (1, N'Kunde1')
GO
INSERT [dbo].[X_Kunden] ([NameID], [Name]) VALUES (2, N'Kunde2')
GO
INSERT [dbo].[X_Kunden] ([NameID], [Name]) VALUES (3, N'Kunde3')
GO
INSERT [dbo].[X_MN_KundenAdr] ([MNID], [KundenID], [AdrID]) VALUES (1, 1, 1)
GO
INSERT [dbo].[X_MN_KundenAdr] ([MNID], [KundenID], [AdrID]) VALUES (2, 2, 1)
GO
INSERT [dbo].[X_MN_KundenAdr] ([MNID], [KundenID], [AdrID]) VALUES (3, 3, 3)
GO
INSERT [dbo].[X_MN_KundenAdr] ([MNID], [KundenID], [AdrID]) VALUES (4, 1, 2)
GO
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).
-
- Beiträge: 88
- Registriert: Sa 18. Jan 2020, 09:56
- OS, Lazarus, FPC: Winux (L 2.2.0 FPC 3.2.2)
- CPU-Target: Windows 64-Bit
Re: Zugriff auf eine n:m Verknüpfung
Nein. Ich meine:
Kunde1 Adresse1
Adresse2
Adresse7
Adresse28
Kunde1 Adresse1
Adresse2
Adresse7
Adresse28
-
- Beiträge: 88
- Registriert: Sa 18. Jan 2020, 09:56
- OS, Lazarus, FPC: Winux (L 2.2.0 FPC 3.2.2)
- CPU-Target: Windows 64-Bit
Re: Zugriff auf eine n:m Verknüpfung
Die Adressen natürlich untereinander
- af0815
- Lazarusforum e. V.
- Beiträge: 6791
- Registriert: So 7. Jan 2007, 10:20
- OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
- CPU-Target: 32Bit (64Bit)
- Wohnort: Burgenland
- Kontaktdaten:
Re: Zugriff auf eine n:m Verknüpfung
Die Ausblendung von mehrfachen gleichen Kundennamen geht nicht, da im Recordset hier immer Kunde + Adresse vorhanden ist. Die unterdrückung der doppelten Namen, muss du anders lösen oder Query mit Subquery lösen. In einem Recordset sehe ich da keine einfache Möglichkeit.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).
-
- Beiträge: 88
- Registriert: Sa 18. Jan 2020, 09:56
- OS, Lazarus, FPC: Winux (L 2.2.0 FPC 3.2.2)
- CPU-Target: Windows 64-Bit
Re: Zugriff auf eine n:m Verknüpfung
Ich weiß nicht, ob ich das Problem richtig erklärt hatte. 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.
Luckner.
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.
Luckner.
- af0815
- Lazarusforum e. V.
- Beiträge: 6791
- Registriert: So 7. Jan 2007, 10:20
- OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
- CPU-Target: 32Bit (64Bit)
- Wohnort: Burgenland
- Kontaktdaten:
Re: Zugriff auf eine n:m Verknüpfung
Wenn das passiert so hast du deine JOINS falsch gesetzt.Luckner hat geschrieben: Do 31. Mär 2022, 13:10 Berlin
Bremen
München
Köln
Berlin
Bremen
München
Köln
Berlin
Bremen
München
Köln
Wenn ich bei meinem SELECTStatement nur eine where Klausel hinzufüge, so kann ich das auf einen Kunden einschränken
Code: Alles auswählen
SELECT dbo.X_Kunden.Name, dbo.X_Adr.Adresse
FROM dbo.X_MN_KundenAdr INNER JOIN
dbo.X_Adr ON dbo.X_MN_KundenAdr.AdrID = dbo.X_Adr.AdrID RIGHT OUTER JOIN
dbo.X_Kunden ON dbo.X_MN_KundenAdr.KundenID = dbo.X_Kunden.NameID
WHERE dbo.X_Kunden.Name = :SQLKunde
Mach das mit den Partametern im JOIN, ausser du weisst wirklich was du machst. Generell gehören so Einschränkungen immer in die where Klausel.Name Adresse
Kunde1 Adresse 1
Kunde1 Adresse 2
Ausserdem sollte man Parameter verwenden, hier habe ich den Parameter SQLKunde verwendet.
Verwendet man im Quelltext so
Code: Alles auswählen
Q.Params.CreateParam(ftString, 'SQLKunde ', ptInput);
Q.ParamByName('SQLKunde ').AsString:= KundenNamen;
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).
-
- Beiträge: 289
- Registriert: Mo 24. Aug 2020, 14:16
- OS, Lazarus, FPC: Ubuntu Xenial 32, Lazarus 2.2.0, FPC 3.2.2
- CPU-Target: i386
Re: Zugriff auf eine n:m Verknüpfung
Wird nicht der Parameter bereits dadurch erzeugt, dass man einen SQL-Text mit einem Bestandteil ':Ausdruck' zuweist? Ich habe jedenfalls noch nie ein Param 'händisch' anlegen müssen, auch nicht bei Zuweisung erst zur Laufzeit.