dedlfix: Inner Join mit subselect und Limit?

Beitrag lesen

Tach!

Dieser eine Datensatz hat eine von den drei motherPlanIds. Von den anderen beiden ist kein Datensatz in der Ergebnismenge. Da kann dann auch keiner mit den anderen Ergebnismengen gejoint werden. Bin mir jetzt nicht sicher ob ich das richtig erklärt habe da ich Deiner Erklärung nicht ganz folgen kann

Doch, hast du richtig beschrieben. Ich hatte mir zwar erst gewünscht, solch eine Datensatzaufstellung zu bekommen, aber letztlich hab ich das Problem doch aus der Aufgabenstellung verstanden. Was du auch noch hättest machen können: Alles überflüssige weglassen. Spaltennamen, die keine verknüpfungsrelevanten Daten liefern und die beiden einfachen Joins sind solche Kandiaten. Im Zweifelsfall lass aber das drin, von dem du dir nicht sicher bist, ob es relevant sein könnte oder nicht. Das nur als nebensächlicher Hinweis. Nun zum Problem. Lies die folgende Beschreibung bitte erstmal ohne "eigenmächtig" Bezüge zu deinem Problem herzustellen. Das Gehirn fängt ja gern gleich damit an, die Antwort auf das Problem einzuordnen.

Ein SQL-Datenbanksystem arbeitet mengenorientiert. Du hast eine oder mehrere vorläufige Ergebnismengen und die werden immer weiter eingeschränkt. Zu Anfang hast du eine große Menge Daten in der Datenbank. Dann kommst du mit einem FROM um die Ecke und das liefert erstmal die Menge aller Daten der angegebenen Tabelle. Auch die Joins liefern jeweils eine Tabelle oder im Falle der Subquerys jeweils eine bereits ausreichend eingeschränkte Menge. Das ist bei dir nicht der Fall, aber dazu später. Jetzt haben wir erstmal 5 Ergebnismengen. Nun kommen die Join-Bedingungen an die Reihe. Die Ergebnismengen werden entsprechend der Bedingung miteinander verknüpft. Aus breederInfo beispielsweise kommen zwei Datensätze in die zusammengeführte Menge, die restliche Menge fällt weg. Auf dieser Menge werden nun nacheinander die anderen Klauseln angewendet: WHERE, GROUP BY, SELECT, HAVING, ORDER BY, LIMIT. Das schränkt die Menge immer weiter ein oder macht etwa anderes mit ihr (zum Beispiel Sortieren).

Deine Subquerys liefern völlig unabhängig von anderen Tabellen jeweils einen Datensatz, wegen des LIMIT 1. Auch sie durchlaufen die generelle Tippeltappeltour, das aber jeweils separat, weil sie im FROM/JOIN der äußeren Query stehen. Bei images hat der Datensatz mit der ID 1 das kleinste Datum. Das ist die Ergebnismenge, weil das LIMIT die einzige Einschränkung ist. Erst nachdem diese Menge entstanden ist, kommt das Joinen an die Reihe. Und das kann lediglich den einen Datensatz verknüpfen. Andere liegen nicht in der Menge. Dein Fehler ist, dass du annimmst, das auf irgendeine Weise die in motherPlan enthaltene Menge eine Rolle beim Auswählen der images-Datensätze spielt. Aber da ist überhaupt kein Bezug darauf in der Subquery. Es ist keine Correlated Subquery. Und zu der Zeit geht auch keine Korrelation zu den anderen Mengen herzustellen, weil das Joinen noch nicht stattgefunden hat. Korrelationen können erst im WHERE oder noch später, im SELECT hergestellt werden. (Das SELECT steht zwar als erstes in der Query, wird aber erst zwischen GROUP BY und HAVING ausgeführt. Ansonsten ist die Ausführungsreihenfolge gleich der (von der Syntax fest vorgegebenen) Anordnung der Klauseln.)

Ich hoffe, dass du jetzt das Problem verstanden hast, und auch dass es sich auf diese Weise nicht lösen lässt.

Wie zu sehen ist, ist die Hauptabelle die motherPlan, davon benötige ich jeden Datensatz. In den beiden Tabellen breederInfo und borntype, kann es maximal nur einen zugehörigen Datensatz für die motherPlan geben oder eben keinen deswegen der normale Left Join damit alle Datensätze der motherplan auch ausgegeben werden.

Diese beiden Tabellen und Joins sind für das Problem nicht weiter relevant. Du kannst sie im Prinzip auch weglassen und erst dann wieder einfügen, wenn du die anderen beiden Verknüpfungsprobleme gelöst hast - oder eingesehen hast, dass das aus Prinzip so nicht lösbar ist.

Wurde es jetzt transparenter?

Nein ;) war schon transparent genug gewesen.

das müsste doch mit Left-Joins gehenoder?

Vermutlich nicht. Ich wüsste nicht wie. Mir ist bis jetzt auch keine andere Lösungsmöglichkeit mit nur einer Query eingefallen.

Wenn nicht müsste es doch eine andere simple Möglichkeit geben

Mithilfe der abfragenden Umgebung kannst du zu einer Lösung kommen. Du kannst die Subquerys aus der Query entfernen. Beim Durchlaufen über die Ergebnismenge der übriggebliebenen Query (motherPlan, breederinfo, bornType) feuerst du für jeden Datensatz je eine Query auf images und information ab. Da muss aber als Bedingung rein, die motherPlanId mit der übergebenen motherPlan-Id aus dem Durchlauf zu vergleichen. Das schränkt deren Ergebnismengen gemäß deinem Beispiel auf die zwei Datensätze passend zur motherPlan-Id ein, das LIMIT nach dem Sortieren lässt dann genau den einen gewünschten übrig. Das "Joinen" musst du dann an der Stelle in deinem Programm machen.

Die Alternative dazu wäre, diesen beschriebenen Vorgang in einer Stored Procedure stattfinden zu lassen. Das wird aber anzunehmenderweise komplettes Neuland für dich sein und eine Menge Lernaufwand erfordern.

dedlfix.