![]() |
Datenbank: Access • Version: 2003 • Zugriff über: TADOQuery
SQL-Abfrage über n-m-Beziehung
Hallo,
wahrscheinlich gibt es schon viele Einträge zu diesem Thema. Aber ich fand keinen. :oops: Problembeschreibung: Zwei Tabellen: 1. Tabelle: GERICHT ID Gericht -------------- 0 Schnitzel 1 Forelle 2 Steak 2. Tabelle: BEILAGE ID Beilage ------------- 0 Nudeln 1 Reis 2 Kartoffeln Um die beiden Tabellen zu verknüpfen gibt es eine 3. Tabelle "GERICHT_BEILAGE" mit den beiden Schlüsseln GerichtID und BeilageID. GerichtID BeilageID ------------------- 0 0 0 2 1 2 2 1 ... Wie finde ich jetzt per SQL-Abrage z. B. alle Gerichte, die Nudeln UND Kartoffeln als Beilage haben? Folgender Code gibt jedenfalls eine leere Datenmenge zurück:
Delphi-Quellcode:
Kann mir jemand sagen wie das Problem heißt und nach was ich suchen muss oder hat jemand gerade eine Lösung dafür?
SELECT GERICHT.Gericht, BEILAGE.ID
FROM BEILAGE INNER JOIN (GERICHT INNER JOIN GERICHT_BEILAGE ON GERICHT.ID = GERICHT_BEILAGE.GerichtID) ON BEILAGE.ID = GERICHT_BEILAGE.BeilageID WHERE (BEILAGE.ID=0) And (BEILAGE.ID=2); Gruß e-gon |
AW: SQL-Abfrage über n-m-Beziehung
Du fragst ab, in welcher Zeile
SQL-Code:
.
(BEILAGE.ID=0) And (BEILAGE.ID=2)
Bislang kann ein Wert nur einen Wert haben, aber nicht zwei gleichzeitig :stupid: |
AW: SQL-Abfrage über n-m-Beziehung
Suchst Du vielleicht eher so etwas?
SQL-Code:
Eine Beilage kann ja wahrscheinlich nicht gleichzeitig 2 verschiedene IDs haben.
SELECT
G.Gericht, B.ID FROM Beilage B INNER JOIN GERICHT_BEILAGE GB ON GB.BeilageID = B.ID INNER JOIN Gericht G ON GB.GerichtID = G.ID WHERE B.ID IN (0, 2) |
AW: SQL-Abfrage über n-m-Beziehung
SQL-Code:
so sollte es gehen.
select distinct GERICHT.Gericht
from GERICHT join GERICHT_BEILAGE GB1 on (GERICHT.ID=GB1.GerichtID) join BEILAGE B1 on (GB1.BeilageID=B1.ID and B1.Beilage='Kartoffeln') join GERICHT_BEILAGE GB2 on (GERICHT.ID=GB2.GerichtID) join BEILAGE B2 on (GB2.BeilageID=B1.ID and B2.Beilage='Reis') Alternativ könnte man auch exists verwenden, aber das ist etwas langsamer, je nach verwendeter DB. Gruß K-H P.S. Spätestens wenn nach ein paar Monaten eine solche Abfrage nochmals angeschaut wird, fragt man sich "und was steckt hinter ID=2?" Darum sollte man solche Verkürzungen meiden wann immer es geht, oder einen Kommentar dazu schreiben. |
AW: SQL-Abfrage über n-m-Beziehung
In groben Zügen:
Finde alle Gerichte, die entweder die Beilage1 oder Beilage2 haben und nimm nur die Gerichte, die zwei Treffer haben. |
AW: SQL-Abfrage über n-m-Beziehung
Vielen Dank für die schnellen Antworten!
@DeddyH: Der "IN"-Befehl ist doch auch wieder "OR" und nicht "AND", oder? @p80286: Exists ist aber vielleicht die einfachere Lösung, oder? Gruß e-gon |
AW: SQL-Abfrage über n-m-Beziehung
Also so funktioniert es, ist aber wohl ziemlich langsam...
Code:
SELECT GERICHT.Gericht
FROM GERICHT WHERE (EXISTS(SELECT GERICHT_BEILAGE.GerichtID, BEILAGE.ID FROM BEILAGE INNER JOIN GERICHT_BEILAGE ON BEILAGE.ID = GERICHT_BEILAGE.BeilageID WHERE (GERICHT_BEILAGE.GerichtID=GERICHT.ID) AND (BEILAGE.ID=0))=True) AND (EXISTS(SELECT GERICHT_BEILAGE.GerichtID, BEILAGE.ID FROM BEILAGE INNER JOIN GERICHT_BEILAGE ON BEILAGE.ID = GERICHT_BEILAGE.BeilageID WHERE (GERICHT_BEILAGE.GerichtID=GERICHT.ID) AND (BEILAGE.ID=2))=True); |
AW: SQL-Abfrage über n-m-Beziehung
Da hast Du etwas falsch verstanden
Bisher sind Dir verschieden Strategien vorgeschlagen worden wie Du an deine Daten kommen könntest. Je nach betroffener Datenmenge ist es z.B. sinnvoll zuerst die Gerichte zu selektieren, die zwei (oder mehr?) Beilagen haben. Und diese dann auf 'Kartoffeln' und 'Reis' zu prüfen. Alternativ wählst Du erst alle Gerichte mit Reis oder Kartoffeln als Beilage und schaust welche davon Reis und Kartoffeln haben. Da führen viel (Um)Wege nach Rom. (Wenn Du meinen Vorschlag um die Beilage ergänzt bekommst Du eine wundersame Datenvermehrung) Mit exists meinte ich so etwas z.B. SQL-Code:
SQL-Code:
Du selektierst ein Gericht mit einer Beilage und prüfst ob es hierzu auch die zweite Beilage gibt.
select distinct GERICHT.Gericht
from GERICHT join GERICHT_BEILAGE GB1 on (GERICHT.ID=GB1.GerichtID) join BEILAGE B1 on (GB1.BeilageID=B1.ID and B1.Beilage='Kartoffeln') where exists (select * from GERICHT_BEILAGE GB join Beilage on (Beilage.ID=gb.BeilageID and Beilage.Beilage='Reis') where gb.gerichtID=GerichtID) Gruß K-H |
AW: SQL-Abfrage über n-m-Beziehung
Mein Weg nach Rom, der auch mit mehr als 2 Beilagen funktionieren sollte:
SQL-Code:
Die Gerichtsbezeichnung aus der Gerichtstabelle kann man sich dann ja noch dazu joinen...
Select GB.GerichtID From
(Select * From GERICHT_BEILAGE Where BeilageID in ([Liste der BeilagenIDs])) GB Group By GB.GerichtID Having count(GB.GerichtID)=[Anzahl der Beilagen] Edit: Ich sehe gerade, dass das glaub ich komplitzierter ist als es sein muss, den inneren Subselect braucht man glaub ich gar nicht. |
AW: SQL-Abfrage über n-m-Beziehung
Code:
oder sowas wie
select *
from GERICHT g where exists ( select 1 from GERICHT_BEILAGE g1 where BeilageID=0 and g1.gerichtID=g.iD ) and exists ( select 1 from GERICHT_BEILAGE g1 where BeilageID=2 and g1.gerichtID=g.iD )
Code:
Typische DWH Anforderung 'Käufer, die X kaufen, kauften auch ....'
select GerichtID
from GERICHT_BEILAGE where BeilageID in (0,2) group By GerichtID having Count(distinct BeilageID)=2 Bei dynamischer Anforderung (d.h. Beilagen können in einem Filter per Multiselect ausgewählt werden), würde ich die 2. Variante wählen, wobei die 'IN' Klausel und das erwartete Count-Resultat durch die Selektion bestimmt wird. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 06:18 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz