Datenbank Abfrage
-
Million Voices schrieb:
Sub-Select auf die Verknüpfungstabelle? Warum? Schau Dir noch mal den Aufbau der Tabelle Autor an...
...ja?
Vielleicht solltest du besser nochmal gucken?
-
hustbaer schrieb:
Vielleicht solltest du besser nochmal gucken?
Ähm ja, hust... Ich nehm's zurück.
-
Also zu 1) hab ich jetzt schon mal eine Lösung. Hab die Namen nun zwar auf englisch aber es kommt das richtige raus. Nur komischerweise gibt er den Author doppelt zurück . Hmm...
Select firstname,lastname from author inner JOIN author2book on author.authorID in(SELECT author2book.authorId from author2book where bookID = 2)
-
Wie kommst du denn auf das Konstrukt
INNER JOIN ... ON xxx IN ()
Das habe ich in 15 Jahren SQL noch nie gesehen. Ist schon klar dass es möglich ist, aber macht für mich überhaupt keinen Sinn.Egal, der Grund dass du es doppelt bekommst ist dass du von
where Autor_ID in
zuINNER JOIN
umgestiegen bist.
So funktioniert ein Join halt - wenn der Author (linke Join Seite) 2 Bücher geschrieben hat (rechte Join Seite), dann bekommst du 2 Zeilen im Ergebnis. Wobei die linke Seite dann halt dupliziert wird.Ich würde hier einfach mit
WHERE xxx IN
oder auch mitWHERE EXISTS
arbeiten.
-
Lösung zu 2)
Select firstname,lastname from author inner JOIN author2book where author.authorID in (Select author2book.AuthorID from author2book where author2book.BookID = (Select book.BookID from book where book.Title = 'Potter') )
Und bei inner join verwendet man statt where wohl on so hab ich's gelernt und so steht es auch bei w3schools
-
hustbaer schrieb:
So funktioniert ein Join halt - wenn der Author (linke Join Seite) 2 Bücher geschrieben hat
Ich hab da aber nur 1 Buch drin. Trotzdem bekomm ich 2 mal das gleiche. Kann doch nicht sein.... Die können doch nicht verlangen dass ich Select Distinct mache. Da ist dann die Anfrage noch irgendwo nicht ganz richtig....
-
Oioioioi...
Also ein JOIN versucht jede Zeile des linken Teils mit jeder Zeile des rechten Teils zu kombinieren.
Dabei entstehen N * M potentielle Zeilen (mit N = Anzahl Zeilen im linken Teil und M = Anzahl Zeilen im rechten Teil).
Im "ON" Teil gibt man dabei an welche Bedingung erfüllt sein muss damit die Kombination der beiden Teile "erwünscht" ist, also "erzeugt" werden soll.Die verschiedenen JOIN Typen:
CROSS JOIN: Es gibt keinen "ON" Teil, es werden alle Kombinationen erzeugt. Eben das "Kreuzprodukt" der beiden Tabellen (Teile).
INNER JOIN: Es werden nur Kombinationen erzeugt für die der "ON" Teil erfüllt ist.
LEFT OUTER JOIN: Es werden alle Kombinationen erzeugt für die der "ON" Teil erfüllt ist. Zusätzlich werden alle Zeilen des linken Teils zurückgegeben für die der "ON" Teil bei keiner Kombination erfüllt war. Dabei (=bei diesen zusätzlichen Zeilen) werden alle Spalten im Ergebnis die vom rechten Teil stammen würden als NULL zurückgegeben.
RIGHT OUTER JOIN: Es werden alle Kombinationen erzeugt für die der "ON" Teil erfüllt ist. Zusätzlich werden alle Zeilen des rechten Teils zurückgegeben für die der "ON" Teil bei keiner Kombination erfüllt war. Dabei werden alle Spalten im Ergebnis die vom linken Teil stammen würden als NULL zurückgegeben.
FULL OUTER JOIN: Es werden alle Kombinationen erzeugt für die der "ON" Teil erfüllt ist. Zusätzlich werden alle Zeilen des linken und rechten Teils zurückgegeben für die der "ON" Teil bei keiner Kombination erfüllt war. Dabei werden alle Spalten im Ergebnis die vom jeweils nicht beteiligten Teil stammen als NULL zurückgegeben.
Wenn wir uns jetzt deine Query ansehen...
SELECT firstname, lastname FROM author INNER JOIN author2book ON author.authorID IN (SELECT author2book.authorId FROM author2book WHERE bookID = 2)
Es werden also alle Kombinationen aus Zeilen in
author
"cross" Zeilen inauthor2book
probiert.
Die wo die Bedingungauthor.authorID IN (SELECT author2book.authorId FROM author2book WHERE bookID = 2)
zutrifft werden zurückgegeben.Diese Bedingung ist nun aber überhaupt nicht vom rechten JOIN Teil abhängig.
Du machst ja im "IN" Teil ein SELECT aufauthor2book
, dieauthor2book
-Felder die du darin referenzierst beziehen sich also NICHT auf den rechten JOIN-Teil sondern auf das SELECT innerhalb der Klammern!
D.h. angenommen die QuerySELECT author2book.authorId FROM author2book WHERE bookID = 2
würde als Ergebnis 1 und 2 zurückgeben, dann wäre deine "ON" Bedingung:
author.authorID IN (1, 2)
Und nu nochmal: Es werden alle N * M Konbinationen aus
author
undauthor2book
Zeilen probiert, wobei du in der "ist die Kombination erwünscht"-Bedingung den Inhalt derauthor2book
Zeile komplett ignorierst. D.h. du bekommst im Ergebnis zeilen der Autoren 1 und 2, und zwar so oft dupliziert wie es Zeilen inauthor2book
gibt!(Und deswegen bekommst du im Ergebnis Duplikate. Derzeit bekommst du alles "nur" doppelt, weil du in
author2book
bloss zwei Zeilen hast. Würdest du mehrauthor2book
Zeilen einfügen (egal mit welchen IDs!), würdest du alles 3x, 4x - beliebig oft bekommen.)Also schreib es ohne JOIN, oder so wie normale Programmierer einen JOIN schreiben.
-
hustbaer schrieb:
Wie kommst du denn auf das Konstrukt
INNER JOIN ... ON xxx IN ()
Ich würde hier einfach mit
WHERE xxx IN
oder auch mitWHERE EXISTS
arbeiten.wenn ich
select firstname, lastname from author, author2book where author.author.id = (Select author2book.authorid from author2book where bookId = 1 )
mache, bekomm ich immer noch die Duplikate. Jetzt benutz ich kein join mehr...
-
select firstname, lastname from author where author.author.id = (Select author2book.authorid from author2book where bookId = 1 )
Jetzt immer noch? Wenn ja, würde ich gerne den Inhalt der Tabellen sehen.
-
Jetzt nicht mehr. Der inner join war also nie nötig
-
Peter_Mueller schrieb:
wenn ich
select firstname, lastname from author, author2book where author.author.id = (Select author2book.authorid from author2book where bookId = 1 )
mache, bekomm ich immer noch die Duplikate. Jetzt benutz ich kein join mehr...
Doch, klar verwendest du immer noch nen JOIN.
FROM author, author2book
ist bloss 'ne alternative Schreibweise für
FROM author CROSS JOIN author2book
Und nein, natürlich war der JOIN nie nötig. Wurde auch nie behauptet