dedlfix: Inner Join mit subselect und Limit?

Beitrag lesen

Tach!

ich hatte/habe da wohl einen totalen Denkfehler Noch wäre die Möglichkeit meine Tabellen und das Setzen der ID's anzupassen, weiss nicht ob das klüger wäre.

Ich wüsste nicht, wie man das umstellen sollte. Du hast eine 1:n-Beziehung. Und davon möchtest du auf der n-Seite Gruppen bilden und jeweils einen Datensatz aus der Gruppe haben. Das ist ein generell nicht lösbares Problem im (Standard-)SQL-Umfeld. Jedenfalls nicht dann, wenn du Daten aus Feldern haben möchtest, die nicht im GROUP BY aufgeführt sind und auch nicht mit einer Aggregatfunktion zusammengefasst wurden. Angenommen, du möchtest das kleinste und größte Datum aus einem bestimmten Feld haben (SELECT MIN(feld), MAX(feld), andere_felder FROM ... GROUP BY ...), dann kommen diese Angaben aus zwei Datensätzen. Aus welchem der beiden Datensätze sollen nun die anderen Felder genommen werden? Und was genau spräche denn ganz allgemein gesehen, ohne eine spezielle Aufgabenstellung zu kennen (MySQL kann ja keine Gedanken lesen), dagegen, irgendeinen beliebigen anderen Datensatz aus der Gruppe abseits von MAX/MIN heranzuziehen? Eine solche Abfrage ist nicht eindeutig zu beantworten, weswegen die meisten SQL-Systeme solche Querys generell nicht erlauben. MySQL erlaubt es, gibt aber keine Garantie, welche Datensatz-Inhalte in der Ergebnismenge landen.

Das ist das allgemeine GROUP-BY-Problem. GROUP BY wäre aber die einzige (mir einfallende) Möglichkeit, näher an die Lösung zu gelangen, nur um dann festzustellen, dass diese Straße eine Sackgasse ist.

Es wäre nicht weiter schwer, eine Correlated Subquery zu erstellen. Doch die darf dann nur einen einzelnen Wert zurückliefern, weil sie nur im SELECT anstelle eines Feldes oder in einem WHERE anstelle eines Bedingungskriteriums notiert werden kann. Das ist für deinen Fall nicht anwendbar. Viele solcher Querys - für jedes Feld eine - wäre möglich, ist aber sehr unhandlich.

Der Grund für diese Gestaltung der Tabellen war der, dass ich auf einer Webseite die motherplan mit Basis-Daten fülle und auf der anderen Webseite dann Zusatzinfos eintrage wie ich lade Bilkder hoch und trage Information ein. Damit die Tabelle motherplan nicht ewig im Datensatz und dessen felder lang wird , habe ich die Daten aufgeteilt da ich so die Möglichkeit habe die images-tabelle und die information-tabelle auch von anderen Webseiten also von anderen Tabellen zu nutzen die auch images und informations benötigen.

Klassisches 1:n. Die Alternative wäre eine große Tabelle, in der der motherPlan-Anteil mehrfach enthalten wäre. Für jedes image ein Datensatz. Machbar aber sehr unschön. Zieht eine Menge andere Probleme nach sich, beispielsweise das, bei einer Änderung keine Abweichungen zwischen den redundanten Teilen der Datensätzen zu generieren. Das Ergebnis ist dann eine nicht normalisierte statt einer relationalen Datenhaltung.

Ich dachte der Ablauf eines Left Joins und eines Subselect's wäre so. Es wird alles ausgegeben was in der motherplan also der linken Tabelle steht. [...] da die images und die informations natürlich zu einem Datensatz aus der motherplan beliebig viele informationen und Bilder enthalten können würde ich mit einem normalen Left-Join zuviele Datensätze angezeigt bekommen,

Dir fehlt an der Stelle die Einschränkung "pro motherplanId". Die wird in der Subquery nicht berücksichtigt, weil sie gar nicht darin enthalten ist. Und wie schon gesagt, geht das generell nicht.

  1. dann läuft er in den dritten Left-Join und kommt dort in eine schleife da ein subselect dort enthalten ist. Dieser subselect holt sich alle Datensätze und würde die auch ausgeben. nun werden diese Datensätze sortiert und danach limitiert . die Abfrage die im subslect enthalten ist vergelicht hierbei die aus dem Hauptselect der motherplan gefundene motherplan-id. in obigen Beispiel findet dieser subselect also 2 Datensätze und würde durch limit 1 nur einen ausgeben

Und genau das findet so nicht statt.

Ich stutze gerade deshalb, da wenn ich in den subselects die LIMIT Beschränkung weglasse, dann liefert er ja auch alle Datensätze. Das bedeutet doch das er dort auch alles findet.

Ja, die Ergebnismenge der Subquery besteht dann aus 6 statt einem Datensatz. Diese 6 werden anschließend mit der anderen bereits ermittelten Menge (aus motherplan und den beiden Joins) gejoint.

nur bringt er dann 2 Datensätze pro motherPlanId da ja je zwei Datensätze in der images und information enthalten sind. wieso ich dieses Ergebnis des Subselects  dann mit LIMIT nicht beschränken kann leuchtet mir nicht ein

Wegen der anderen Reihenfolge der Ausfühung der Zwischenergebnismengenermittlungen als in deiner Annahme.

Helf mir mal bitte mit welcher Möglichkeit ich das lösen könnte.

Die habe ich schon genannt.

Ich wollte eigentlich vermeiden das mit 2-3 verschieden qwuerys zu erschlagen die ich dann via php in einer Schleife vergleiche.

Auch eine Alternative dazu, die aber nicht minder aufwendig ist. Der Ort der Ausführung ist bei einer Stored Procedure nur ein anderer, die Vorgehensweise in dem Fall ist dieselbe wie unter PHP.

Muss/sollte ich meine db-struktur anders aufbauen?

Lieber nicht. Vom Regen in die Traufe wirds nicht besser.

Die üblicherweise auf einer Webseite angezeigten Datenmengen belasten die Datenbank mit den zusätzlichen Abfragen nicht wirklich. Bleibt nur noch die Anzahl gleichzeitier Requests zu berücksichtigen. Die vermute ich aber in dem Fall als vernachlässigbar gering.

dedlfix.