SQL Query Problem...
-
Hi,
gegeben ist folgende Strutkur:
[Filme] (id, name)
[Darsteller] (id, name)
[Besetzung] (id, filmid, darstellerid)Wie kann ich halbwegs effizent nach einem film suchen, in dem mehrere gegebene Darsteller mitgespielt haben. Also ich möchte z.B. alle Filme haben in denen die Darsteller mit den ids 815, 4711, 1234, 9876 und 1928 mitgespielt haben. Wie mache ich das?
So nach dem Motto:
SELECT id, name FROM Filme JOIN Besetzung ON Filme.id = Besetzung.filmid WHERE Besetzung.darstellerid = 815 OR Besetzung.darstellerid = 4711....Aber so gehts ja logischerweise nicht, da jeder darsteller mit jedem film in einer eigenen Zeile gejoint wurde.
Vielen dank im voraus
template
-
Um nach zwei Schauspielern zu suchen, müßtest du zwei Ausgaben von "Besetzung" parallel durchlaufen:
SELECT f.name FROM Filme AS f INNER JOIN (Besetzung AS b1 INNER JOIN BESETZUNG AS b2 ON b1.filmid=b2.filmid) ON f.id=b1.filmid WHERE b1.darstellerid=815 AND b2.darstellerid=4711;
Für drei oder mehr Darsteller wird dein Join entsprechend länger.
-
SELECT f.name FROM filme f, besetzung b WHERE f.id = b.filmid AND b.darstellerid IN (815, 4711, 1234, 9876, 1928)
Edit:Wenn du die Ausgabe doppelter Datensätze vermeiden willst, schreibe "DISTINCT" zwischen "SELECT" und "f.name"
-
Danke euch beiden für die Antwort
@CStoll
Ja, das mit mehreren Joins hatte ich auch als Grundüberlegung aber für jeden join kommt doch normalerweise eine finaltablle mit einer Zeilenanzahl der Tabelle * der Anzahl der Join Tabelle. Da kommen ja unglaublich große Datenmengen bei raus, wenn ich da mal ein bischen rechne:Filme: ca. 1000 und ich sage jetzt einfach mal ungefähr 40 Darsteller pro Film
1. Join 1000 * 40 = 40.000
2. Join 40000 * 40 = 1.600.000
... = 64.000.000
... = 2.560.000.000Da kann einem ja schwindlig werden;) Gut natürlich muss das Datenbanksystem diese Monstertabelle nicht wirklich erstellen und löst das wahrscheinlich irgendwie anders, aber bleibt da wirklich eine halbwegs lineare effizienz bei weiteren Darstellern?
@Finten
Ganz verstehen tu ichs noch nicht aber ich werds heute Abend mal ausprobieren. Danke.
-
Du kannst dir auch eine Zwischentabelle erstellen, die zu jedem Film die Liste aller Darsteller enthält (auch wenn mir da keine Aggregatfunktion einfällt, die das machen würde). Oder du filterst die einzelnen Zwischentabellen vor, so daß jede nur noch die Filme eines Darstellers enthält.
-
Hatte deine Frage falsch verstanden. Du suchst also Filme, wo Person X _und_ Person Y mitgespielt haben? Meine Abfrage sucht Filme, wo Person X _oder_ Y mitgewirkt haben.
-
Wenn alle Darsteller in einem Film mitgewirkt haben sollen, würde ich so vorgehen:
Die Darsteller, die mitgewirkt haben sollen in eine Tabelle schreiben (Suchvorgaben; darstellerid) und folgende Query benutzen:SELECT f.name FROM filme f WHERE NOT EXISTS ( SELECT * FROM suchvorgaben sv2 WHERE NOT EXISTS ( SELECT * FROM besetzung b3 WHERE b3.darstellerid = sv2.darstellerid AND b3.filmid = f.id ) )
-
möglich wäre:
select filmid from (select count(*) cnt, filmid from besetzung where darstellerid in(815,4711) group by filmid) where cnt=2
oder sonst:
select * from filme f where exists (select null from besetzung where filmid=f.id and darstellerid=815) and exists (select null from besetzung where filmid=f.id and darstellerid=4711);