FB18 - Das Forum für Informatik

fb18.de / Off-Topic / Hard- und Softwarefragen

SQL n:n

SQL n:n 2008-08-06 11:49
Popcorn @Denksport
Ich habe (abstrahiert) eine Tabelle mit drei Int-Werten:
- ID auto_increment
- Object-ID
- Image-ID

Es handelt sich um eine Tabelle für die Verknüpfungen zwischen Objekten und Bildern, diese ist n:n.

Mein Problem besteht darin, dass ich nun eine Liste mit Object-IDs habe und genau die Bild-IDs kennen möchte, die mit allen gegebenen Objekt-IDs verbunden sind.

Beispiel Tabelle:

ID ID_OBJ ID_IMAGE 1  1      1       2  1      2   3  2      1 4  2      2 5  3      1Für id_obj 1,3 soll das Ergebnis also id_image 1 sein.
Für id_obj 1,2 soll das Ergebnis id_image 1 + 2 sein.

So, das müsste komplett in SQL doch einigermaßen machbar sein. Oder was meint ihr? Ich komme leider nicht weiter, weil ich so etwas für gewöhnlich mit Zwischenschritten in meinetwegen PHP lösen würde. Aber hier möchte ich eine Lösung, die komplett über SQL läuft. Einfach aus neugier.

RE: SQL n:n 2008-08-06 14:45
Slater
Wenn die Anzahl der Elemente in der Object-Id-Liste begrenzt ist (n), dann kannst du einen n-fachen Join über die Tabelle machen,
je nach einer Object-Id filtern, der Join geht über die Image-Id.

RE: SQL n:n 2008-08-06 15:22
Anonymer User
Hmm. Ja, das ist schon recht prima. Die Verschachtelung ist bei MySQL auf 255 Tabellen begrenzt. Sollte reichen. Aber die Konstruktion ist schon recht arg. Da braucht man eigentlich doch schon wieder weitere Logik für. Trotzdem danke.

RE: SQL n:n 2008-08-06 15:24
Anonymer User
Anonym posten macht keinen Spaß. Jetzt bekomme ich meine schon-Inflation gar nicht wieder aus dem Posting heraus.

RE: SQL n:n 2008-08-06 15:43
Anonymer User
Okay, da war ich zu voreilig. Magst Du für das Beispiel oben man eine kleine SQL-Query aufschreiben, welche die vob den Objekten 1 und 2 gemeinsam genutzten Bilder auswirft. Bei mir führt das zu keinem guten Ende. Kann auch daran liegen, dass ich seit kurz nach acht Uhr Anleitungen am Bildschirm lese. :-(

RE: SQL n:n 2008-08-06 16:05
Anonymer User
So was meintest Du aber nicht, oder?

CREATE VIEW obj1 AS SELECT * FROM bsp WHERE obj = 1;
CREATE VIEW obj2 AS SELECT * FROM bsp WHERE obj = 2;
CREATE VIEW obj3 AS SELECT * FROM bsp WHERE obj = 3;

SELECT obj1.img FROM obj1,obj2,obj3 WHERE obj1.img = obj2.img AND obj2.img = obj3.img;

DROP VIEW obj1;
DROP VIEW obj2;
DROP VIEW obj3;

RE: SQL n:n 2008-08-06 16:49
Slater
wieso nicht, absehen von 'normaler join' vs 'Views'?

in den Views dürfte reichen, nur die ImgIds zu selektieren statt *

RE: SQL n:n 2008-08-06 19:35
Popcorn
Aber wie soll dann das join aussehen. WHERE bsp.img = bsp.img AND bsp.img = bsp.img ergibt ja nun keinen Sinn. Und beim schachteln von Selects kann man ja keine Bezeichner für das Gesamtergebnis generieren, außer halt den Views. Oder?

Bei den ImgIds stimme ich Dir zu. Aber die Views waren eh nur eine Verzweiflungstat. :-)

RE: SQL n:n 2008-08-06 19:52
Slater
SELECT a.img FROM bsp a, bsp b, bsp c
WHERE a.img = b.img AND b.img = c.img
and a.obj = 1
and b.obj = 2
and c.obj = 3;

RE: SQL n:n 2008-08-06 20:33
Loom
Das geht:
SELECT id_img, COUNT(id_img) FROM `table` WHERE id_obj IN (<ids>) GROUP BY id_img HAVING COUNT(id_img) = <#ids>Prüft welche BilderIDs der Objekte so oft vorkommen wie verschiedene ObjektIDs angegeben sind (#ids = Anzahl ids). Für die IDs '1,2' ist die Anzahl 2, bei '1,2,3' entsprechend 3.

Ist nach nach meiner Logik ohne zu große JOIN Kenntnisse ;)

Edit: Danke für den angenehmen Zeitvertreib :)

RE: SQL n:n 2008-08-06 20:54
Anonymer User
Das geht:
SELECT id_img, COUNT(id_img) FROM `table` WHERE id_obj IN (<ids>) GROUP BY id_img HAVING COUNT(id_img) = <#ids>Prüft welche BilderIDs der Objekte so oft vorkommen wie verschiedene ObjektIDs angegeben sind (#ids = Anzahl ids). Für die IDs '1,2' ist die Anzahl 2, bei '1,2,3' entsprechend 3.

Ist nach nach meiner Logik ohne zu große JOIN Kenntnisse ;)

Edit: Danke für den angenehmen Zeitvertreib :)
Caveat:
Dazu müssen die Datensätze aber eindeutig sein, wenn mehrere Zeilen mit der gleichen Verknüpfung von z.B. Obj 1 und Bild 1 erlaubt sind wird eine vorgeschaltete Gruppierung nötig.