Disclaimer: Dieser Thread wurde aus dem alten Forum importiert. Daher werden eventuell nicht alle Formatierungen richtig angezeigt. Der ursprüngliche Thread beginnt im zweiten Post dieses Threads.
Frage zu den SQL-Übungen
Hi, ich hätte eine Frage zu den SQL Aufgaben, speziell zu den Joins:
Die Musterlösungen der Übungen geben den Join immer an wie in diesem Beispiel:
[color=blue]SELECT DISTINCT firmenname
FROM produkt
JOIN firma
USING(strasse, hausnummer, plz, stadt)[/color]
Ich habe es so gelernt und abgespeichert:
[color=crimson]SELECT DISTINCT f.firmenname
FROM f.firma, p.produkt
WHERE f.strasse, f.hausnummer, f.plz, f.stadt = p.strasse, p.hausnummer, p.plz, p.stadt
[/color]
Meine Frage: Sind diese beiden Formulierungen äquivalent? Ich finde das mit dem Join normalerweise etwas umständlich (hier in diesem Beispiel ja offensichtlich nicht)?
Danke für eure Hilfe…
PS: Die Aufgabe ist aus der Übung 8
Müsste deine WHERE-Clause nicht
WHERE
f.strasse = p.strasse
AND f.hausnummer = p.hausnummer
AND f.plz = p.plz
AND f.stadt = p.stadt
heißen? Ich kenne zumindest kein DBMS, dass deine Variante akzeptiert (was aber wiederum auch nichts heißen muss).
Ich behaupte mal ganz frech in diesem Fall würde ein gutes DBMS die Äquivalenz erkennen und das gleiche tun. Interessant wirds, sobald du andere Joins nutzt, z.B. INNER/OUTER/LEFT OUTER/RIGHT OUTER/FULL OUTER, etc. Der Wikipedia-Artikel zu Joins scheint das zu diskutieren, evtl. schaust du da einfach mal rein: http://en.wikipedia.org/wiki/Left_join#Inner_join. Disclaimer: Besonders viel fachliche Ahnung hab ich von dem Thema allerdings nicht mehr.
Dein eigenes Query hat ein paar Syntaxfehler:
- Im FROM-Clause wird der Alias einer Tabelle HINTER den Namen der Tabelle gestellt. Richtig ist: FROM firma f, produkt p (oder äquivalent FROM firma AS f, produkt AS p).
- Was neverpanic gesagt hat.
Nachdem wir das aus dem Weg geräumt haben, hier die Unterschiede der beiden Queries:
-
Dein Query berechnet erst das kartesische Produkt der Tabellen f und p und filtert dann aus dem Produkt alle Zeilen, die die WHERE-Bedingung erfüllen. Das Query vom Lehrstuhl holt sich aus der Tabelle f wirklich nur die Zeilen, die die Bedingung des Joins (das USING) erfüllen. Der Unterschied sollte sofort offensichtlich werden, wenn du die logische Reihenfolge anguckst, in der ein Query ausgeführt wird: http://blog.sqlauthority.com/2009/04/06/sql-server-logical-query-processing-phases-order-of-statement-execution/
-
Bei einem INNER JOIN (nur “JOIN” ist ein Alias für “INNER JOIN”) macht das effektiv keinen Unterschied, weil das Ergebnis davon immer eine Untermenge des kartesischen Produkts ist. Bei OUTER Joins ist das nicht unbedingt der Fall, denn bei einem OUTER Join können auch Zeilen entstehen, die nicht im kartesichen Produkt enthalten sind.
-
Wird USING statt “f.a=p.a AND f.b=p.b AND …” verwendet, tauchen die angegebenen Felder nur ein einziges Mal im Ergebnis auf. D.h. würdest du ein “SELECT *” machen, dann bekommst du mit deiner Lösung u.a. die Felder “f.strasse, f.plz, p.strasse, p.plz, …” zurück (beachte das f. bzw. p. am Anfang). Mit USING würdest du diese Felder nur einmal bekommen: “strasse, plz, usw…” (ohne f. oder p.).
Vielen Dank, eura Antworten haben mir geholfen! Habe das JOIN jetzt besser verstanden. Nun zu einer weiteren Übung:
Personal(PersonalNr, Nachname, Vorname, Position, Anrede,
Geburtsdatum, Einstellung, Straße, Ort, Region, PLZ, Land,
TelefonPrivat, DurchwahlBüro, Bemerkungen, Vorgesetzter)
Bestellung(BestellNr, ↑KundenCode, ↑PersonalNr, Bestelldatum,
Lieferdatum, Versanddatum, ↑FirmenNr, Frachtkosten, Empfänger,
Straße, Ort, Region, PLZ, Bestimmungsland)
Aufgabe: 7. Für wie viele Kunden hat der Mitarbeiter Buchanan schon Bestellungen
abgewickelt?
Die Lösung laut Aufgabenblatt:
SELECT COUNT(DISTINCT KundenCode) AS Kunden, Nachname
FROM Personal P, Bestellung B
WHERE B.PersonalNr = P.PersonalNr
AND P.Nachname LIKE ‘Buchanan’
Meine Lösung:
SELECT COUNT (B.BestellNr)
FROM Bestellung B, Personal P
WHERE P.Personalnr = B.PersonalNr
AND P.Nachname LIKE ‘Buchanan’
Wieso ist meine Lösung falsch?! Ich dachte da BestellNr Primärschlüsel ist, kann es eh nur einmal vor kommen. Wenn ich dann die verschiedenen BestelNr zähle (COUNT) müsste doch auch das Richtige heraus kommen oder?
ich verstehe das so dass hier nach der anzahl verschiedener Kunden gesucht wird. Mit deiner Anfrage suchst du nach verschiedenen Bestellungen.
D.h. wenn Herr Mayer 10mal bei dem Buchanan was bestellt hat und Herr Müller 2mal, dann zählt deine Anfrage 12, die Musterlösung zählt dann nur 2.
ein group by nach der kundenummer sollte helfen