Schnittmenge bilden mit MySQL
Marius
- datenbank
0 André Laugks0 Marius
0 Ilja0 Marius
Hallo zusammen!
Heute musste ich leider feststellen dass MySQL den INTERSECT-Befehl nicht untertützt. Nun suche ich eine Möglichkeit die Funktion von INTERSECT in MySQL nachzubilden. Es geht um folgende Tabelle:
Tabelle: Betriebsdaten_Stammdaten
Bd_Stamm_Id, Bd_Id_fk, Bd_Stamm_Wert, Buch_Datum
1|1|500|1217800812
2|1|400|1217887212
9|1|1500|1217973612
10|1|2000|1218060012
11|1|1200|1218146412
12|3|10000|1217800812
13|3|4000|1217887212
14|3|7000|1217973612
15|3|6000|1218060012
19|433|1000|1217800812
20|433|1200|1217887212
21|433|1500|1217973612
24|435|1321|1218060012
Wie bilde ich jetzt eine Verknüpfung von select-Befehlen um Schnittmengen zu ermitteln wie z.B.:
SELECT Buch_Datum from Betriebsdaten_Stammdaten WHERE Bd_Id_fk = 1
INTERSECT
SELECT Buch_Datum from Betriebsdaten_Stammdaten WHERE Bd_Id_fk = 3
INTERSECT
SELECT Buch_Datum from Betriebsdaten_Stammdaten WHERE Bd_Id_fk = 433
in MySQL ab?
Hierbei will ich die Schnittmenge der Buchnungsdaten der Datensätze mit
Bd_Id_fk 1, 3 und 433 ermitteln.
Ich habe gehört dass man das mit einer Verkettung von join-Befehlen realisieren kann, aber wie?
Ihr würdet mir echt einen rießen Gefallen tun wenn jemand eine Lösung für diese Problem hat.
Schöner Gruß Marius
Hallo!
SELECT Buch_Datum from Betriebsdaten_Stammdaten WHERE Bd_Id_fk = 1
INTERSECT
SELECT Buch_Datum from Betriebsdaten_Stammdaten WHERE Bd_Id_fk = 3
INTERSECT
SELECT Buch_Datum from Betriebsdaten_Stammdaten WHERE Bd_Id_fk = 433
INTERSECT bildet, wie Du schon schreibst eine Schnittmenge, aber ehr aus verschiedene Tabellen.
Bei Deinem Vorhaben würde ich ein GROUP BY anwenden.
SELECT Bd_Id_fk, Bd_Stamm_Wert, Buch_Datum FROM Betriebsdaten_Stammdaten WHERE Bd_Id_fk IN (1, 3, 433) GROUP BY Bd_Id_fk, Bd_Stamm_Wert, Buch_Datum;
André Laugks
@André
Vielen Dank für deine schnelle Antwort, aber deine Abfrage führt leider nicht zu dem gewünschten Ergebnis. Die Abfrage gibt jetzt alle Datensätze mit der Bd_Id_fk 1,3 und 433 aus.
Sie sollte aber nur die Datensätze ausgeben, die gemeinsame Buchungsdaten haben.
Um bei meinem Beispiel zu bleiben:
SELECT Buch_Datum from Betriebsdaten_Stammdaten WHERE Bd_Id_fk = 1
geschnitten mit
SELECT Buch_Datum from Betriebsdaten_Stammdaten WHERE Bd_Id_fk = 3
geschnitten mit
SELECT Buch_Datum from Betriebsdaten_Stammdaten WHERE Bd_Id_fk = 433
sollte als Ergebnis die Buchungsdaten: 1217800812, 1217887212 und 1217973612 liefern. Diese Buchungsdaten hat jeder Datensatz mit Bd_Id_fk = 1, 3, 433 gemeinsam.
Gruß Marius
yo,
Ich habe gehört dass man das mit einer Verkettung von join-Befehlen realisieren kann, aber wie?
zum beispiel mit self joins, sprich dreimal deine tabelle mit jeweils unterschiedlichen alias-namen. in der WHERE klausel selektierst du in der jeweiligen tabelle die Bd_Id_fk und den join der Tabellen in der ON klausel verknüpfst du das datum der tabellen miteinander. ein distinct kannst du dann noch am ende einsetzen, musst du aber nicht, je nachdem, was dir lieber ist.
SELECT distinct t1.Buch_Datum
FROM Betriebsdaten_Stammdaten t1
INNER JOIN Betriebsdaten_Stammdaten t2 ON t2.Buch_Datum= t1.Buch_Datum
INNER JOIN Betriebsdaten_Stammdaten t3 ON t3.Buch_Datum= t2.Buch_Datum
WHERE t1.Bd_Id_fk = 1
AND t2.Bd_Id_fk = 3
AND t3.Bd_Id_fk = 433
;
eine andere lösung besteht mit unterabfragen, die ich eleganter finde.
SELECT t1.Buch_Datum
FROM Betriebsdaten_Stammdaten t1
WHERE t1.Bd_Id_fk = 1
AND t1.Buch_Datum IN (SELECT t2.Buch_Datum
FROM Betriebsdaten_Stammdaten t2
WHERE t2.Bd_Id_fk = 3
)
AND t1.Buch_Datum IN (SELECT t3.Buch_Datum
FROM Betriebsdaten_Stammdaten t3
WHERE t3.Bd_Id_fk = 433
)
;
Ilja
@Ilja
Vielen Dank für deine Hilfe:-) Das ist genau das was ich suche. Du hast mir echt einen riesen Gefallen getan:-). Hab mir nämlich echt ziemlich lange den Kopf darüber zerbrochen, dabei war es, jetzt wo ich die Lösung sehe, doch nicht so schwer.
Ich finde die Lösung mit den Unterabfragen auch eleganter.
Nochmals Danke
Lieber Gruß
Marius