Lass uns das langsam aufbauen.
Erstens können über das Erhalten nur die Informationen über Sterne sehen: (! Könnte dies bekannt vorkommen sollte)
SELECT name AS starName, (class + 7) * intensity * 1000000 AS starTemp
FROM Stars
WHERE starId < 100
Wir bekommen eine Liste aller Sterne, deren starId
weniger als 100 (die WHERE
Klausel), griff nach dem Namen und berechnete die Temperatur. An dieser Stelle brauchen wir keinen eindeutigen Bezug zur Quelle.
Als nächstes müssen wir Planeteninformationen hinzufügen. Was ist mit einem INNER JOIN
(beachten Sie, dass das eigentliche Schlüsselwort INNER
optional ist)?
SELECT Stars.name as starName, (Stars.class + 7) * Stars.intensity * 1000000 AS starTemp,
Planets.name as planetName
FROM Stars
INNER JOIN Planets
ON Planets.starId = Stars.starId
WHERE Stars.starId < 100
Die ON
Klausel eine =
verwendet (gleich) Zustand Planeten zu verbinden, um den Stern, den sie umkreisen; sonst würden wir sagen, dass sie mehr als einen Stern umkreisten, was sehr ungewöhnlich ist! Jeder Stern ist für jeden Planeten einmal aufgeführt, aber das ist zu erwarten.
... Außer jetzt haben wir ein Problem: Einige unserer Sterne von der ersten Abfrage verschwunden! Die (INNER) JOIN
verursacht nur Sterne mit mindestens einem Planeten gemeldet werden. Aber wir müssen immer noch Sterne ohne Planeten melden! Was ist mit einem LEFT (OUTER) JOIN
?
SELECT Stars.name as starName, (Stars.class + 7) * Stars.intensity * 1000000 AS starTemp,
Planets.name as planetName
FROM Stars
LEFT JOIN Planets
ON Planets.starId = Stars.starId
WHERE Stars.starId < 100
... Und wir haben alle Sterne zurück, mit planetName
null
zu sein (und nur einmal erscheinen), wenn es keine Planeten für diesen Stern sind. Gut soweit!
Jetzt müssen wir die Planetentemperatur hinzufügen. Sollte einfach sein:
SELECT Stars.name as starName, (Stars.class + 7) * Stars.intensity * 1000000 AS starTemp,
Planets.name as planetName, starTemp - (50 * Planets.orbitDistance) as planetTemp
FROM Stars
LEFT JOIN Planets
ON Planets.starId = Stars.starId
WHERE Stars.starId < 100
... außer, dass auf den meisten RDBMS Sie einen Syntaxfehler erhalten werden, das System unter Angabe nicht starTemp
finden. Was ist los? Das Problem ist, dass der neue Spaltenalias (Name) nicht (normalerweise) verfügbar ist, bis nach der SELECT
Teil der Anweisung ausgeführt wird.Was bedeutet, wir müssen wieder in die Berechnung setzen:
SELECT Stars.name as starName, (Stars.class + 7) * Stars.intensity * 1000000 AS starTemp,
Planets.name as planetName,
((Stars.class + 7) * Stars.intensity * 1000000) - (50 * Planets.orbitDistance) as planetTemp
FROM Stars
LEFT JOIN Planets
ON Planets.starId = Stars.starId
WHERE Stars.starId < 100
(beachten Sie, dass die db sein kann eigentlich intelligent genug, um nur einmal die starTemp
Berechnung auszuführen pro-line, aber wenn Sie schreiben es zweimal erwähnen in diesem Kontext).
Nun, das ist etwas chaotisch, aber es funktioniert. Hoffentlich werden Sie daran denken, beide Referenzen zu ändern, wenn das notwendig ist ...
Glücklicherweise können wir den Stars
Teil davon in eine Unterabfrage verschieben. Wir müssen nur einmal die Berechnung für starTemp
auflisten!
SELECT Stars.starName, Stars.starTemp,
Planets.name as planetName,
Stars.starTemp - (50 * Planets.orbitDistance) as planetTemp
FROM (SELECT starId, name AS starName, (class + 7) * intensity * 1000000 AS starTemp
FROM Stars
WHERE starId < 100) Stars
LEFT JOIN Planets
ON Planets.starId = Stars.starId
Ja, das sieht aus wie ich es schreiben würde. Sollte im Wesentlichen an jedem RDBMS arbeiten.
Beachten Sie, dass die Klammer in Stars.starTemp - (50 * Planets.orbitDistance)
nur für die Klarheit für den Leser da ist, würde die Bedeutung der Mathematik unverändert bleiben, wenn sie entfernt wurden. Unabhängig davon, wie gut Sie Operator-Vorrangregeln kennen, setzen Sie beim Mischen immer Klammern. Dies wird besonders vorteilhaft, wenn es sich um OR
s und AND
s in JOIN
und WHERE
Bedingungen handelt - viele Menschen verlieren den Überblick darüber, was bewirkt wird.
Beachten Sie auch, dass die implizite Joinsyntax (die durch Komma getrennte FROM
-Klausel) im Allgemeinen als schlecht oder auf einigen Plattformen als absolut veraltet gilt (Abfragen werden zwar weiterhin ausgeführt, aber die DB kann Sie schimpfen). Es macht auch bestimmte Dinge - wie LEFT JOIN
s - schwierig zu tun, und erhöht die Möglichkeit, sich versehentlich zu sabotieren. Also bitte, vermeide es.
Eigentlich würden wir bevorzugen, dass es _wasnot_ ein Bild, vor dem Text war; das macht es viel einfacher, es in Tools für die Ausführung unserer eigenen Tests zu speichern. Unter anderem scheinen Sie einen Syntaxfehler zu haben: "stars.starid <100 = planets.planetid" (wenn die db das akzeptiert, kann ich garantieren, dass Sie keine korrekten Ergebnisse erhalten). In Zukunft würden wir uns über eine bessere Beschreibung dessen im Klaren sein, was speziell nicht funktioniert und was Sie erhalten sollten ("bei diesen Startdaten sollte mein Abfrageergebnis so aussehen ..."). Dies ist besser geschrieben als einige erste Fragen, die ich gesehen habe, obwohl ... –
Großartig, wird dies im Hinterkopf behalten. Vielen Dank. – verkter