Veröffentlicht 30. November 20177 j Hallo, Ich habe einer Frage zu SQL-Anweisung und hoffe, dass ich es gut rüber bringen kann. Ich habe ein kleines Programm geschrieben (mein Projekt), dabei handelt es sich um die Berechnung einer Vollfolierung und Teilfolierung von einem KFZ. Dieses Programm hat 2 Funktionen. 1. Man kann die Marke, Modell, Typ, Jahr usw auswählen und zum Schluss bekommt man den Preis für die Vollfolierung 2. Man kann die qm, die man an Folie braucht eintragen und die Folie auswählen und wieder wird berechnet. Da ich für mein Projekt, die Datenbank in der 3. Normalform normalisiert habe, muss ich nun meine SQL-Anweisungen erneuern. Die erste Abfrage habe ich hinbekommen. Da soll er mir alle Marken nur einmal ausgeben. Bei der 2. Abfrage soll er dann nur die Modelle ausgeben anhand der gewählten Marke, die vorher ausgewählt wurde. Aber mein Befehl funzt nicht. Mir zeigt es die Modelle leider nicht an. Hier mal der SQL-Befehl von Marke (der funktioniert) function marke() { $sql = "Select DISTINCT marke_bezeichnung FROM fahrzeug Left JOIN marke ON marke.marke_id = fahrzeug.marke_id Where marke.marke_id = fahrzeug.marke_id"; return $sql; Und hier der SQL-Befehl von Modell, der nicht geht. function model($marke) { $sql = "Select DISTINCT modell_bezeichnung FROM fahrzeug Left JOIN modell ON modell.modell_id = fahrzeug.modell_id Where modell.modell_id = fahrzeug.modell_id AND marke_bezeichnung = '" . $marke ."'"; return $sql; Und hier noch die Datei Marke (dort wird ein Select ausgegeben mit allen Marken). Die Marke, die man dann gewählt hat, muss dem Modell übergeben werden. <body> <div id="body" align="center"> <?php include("db.php"); $res = mysqli_query(connect(), marke()); $num = mysqli_num_rows($res); mysqli_close($con); if($num > 0) echo ""; else echo "Keine Ergebnisse<br>"; while ($dsatz = mysqli_fetch_assoc($res)) { $make[] = $dsatz["marke_bezeichnung"]; } ?> <p>Bitte treffen Sie Ihre Auswahl:</p> <fieldset style="width:300px"> <legend>Vollfolierung</legend> <form action="projekt_model.php" method= "post"> <select name="marke"> <?php foreach($make as $single_make): ?> <option value="<?php echo $single_make ?>" ><?php echo $single_make ?></option> <?php endforeach; ?> </select> <p><input type="submit"> <input type="reset"></p> </fieldset> </form> Und Hier ist die Datei Modell, der die Marke übergeben werden muss. <body> <div id="body" align="center"> <?php if(isset($_POST["marke"])){ ?> <?php include("db.php"); $res = mysqli_query(connect(), model($_POST["marke"])); $num = mysqli_num_rows($res); mysqli_close($con); if($num > 0) echo ""; else echo "Keine Ergebnisse<br>"; while ($result = mysqli_fetch_assoc($res)) { $model[] = $result["modell_bezeichnung"]; } ?> <fieldset style="width:300px"> <legend>Modell</legend> <form action="projekt_type.php" method="post"> <p>Marke: <?php echo $_POST["marke"] ?></p> <input type="hidden" name="marke" value="<?php echo $_POST["marke"] ?>" /> <select name="model"> <?php foreach($model as $single_model): ?> <option value="<?php echo $single_model ?>" ><?php echo $single_model ?></option> <?php endforeach; ?> </select> <p><input type="submit"> <input type="reset"></p> </fieldset> </form> <?php } else { ?> <p>Bitte eine Marke auswählen</p> <a href="projekt_marke.php">Zurück</a> <?php } ?> </div> </body></html> Ich hoffe, war nicht zuviel des guten. Lieben Dank Bearbeitet 30. November 20177 j von checkaline
30. November 20177 j Hi. Ich hab grad nicht allzu viel Zeit, daher beschränke ich mich aufs SQL: Zum 1. SQL: "select distinct marke_bezeichnung from marke" macht doch das was du willst - oder? Warum der Join auf Fahrzeug? Du übergibst ja auch keine Parameter.. Infos zum 2. SQL bitte ignorieren, habe ich verlesen Gruß, Memento Bearbeitet 30. November 20177 j von Memento
30. November 20177 j $sql = "Select DISTINCT modell_bezeichnung FROM fahrzeug Left JOIN modell ON modell.modell_id = fahrzeug.modell_id Where modell.modell_id = fahrzeug.modell_id AND marke_bezeichnung = '" . $marke ."'"; Von wo kommt denn das "marke_bezeichnung"? Und was bedeutet "nicht geht"? Bekommst du eine Fehlermeldung oder einfach kein Ergebnis? Wenn du das Problem auf den SQL-Part runterbrechen kannst, würde es mehr Sinn machen uns deine Datenstrukturen als den PHP-Code zu zeigen. Du solltest dich noch zum Thema SQL-Injection einlesen: https://stackoverflow.com/questions/60174/how-can-i-prevent-sql-injection-in-php/60496#60496
30. November 20177 j Hallo @checkaline! Allgemein meine GoTo-Referenz zum Thema JOINs: https://blog.codinghorror.com/a-visual-explanation-of-sql-joins/ Zu deinem konkreten Problem: Ich verstehe die Modellierung noch nicht ganz. Wir gehen davon aus, ein Fahrzeug hat bei dir folgende relevante Eigenschaften. Modell Marke Typ Jahr Also z.B. ein Ford Galaxy Baujahr 2010. Marke: Ford Modell: Galaxy Jahr: 2010 Typ: Minivan Also eine Tabelle Modell mit ID und Name, eine Tabelle Jahr mit ID und zugehörigem Baujahr (evtl. Clustern oder Redundanz in Kauf nehmen, Tabelle sparen und in Fahrzeug direkt das Jahr schreiben), eine Tabelle Marke mit ID und Name und eine Tabelle Typ mit ID und Name. Aus der Tabelle Fahrzeug referenzierst du die jeweiligen IDs und gibst den Rest über JOINs aus. Ein Tipp: Nimm die Bezeichner beim Bauen der Abfragen mit. Wenn es dir zu lang ist "Modell.Name" zu schreiben, vergib ein Alias wie z.B. "m". So weißt du oder wer auch immer deinen Code liest, worum es sich handelt. Mir fehlt, was genau "nicht funzt". Hast du die Abfrage mal direkt im DBMS (vermutlich phpMyAdmin) abgefeuert? Wenn ja, was kam da raus? Gruß, Goulasz
30. November 20177 j Autor vor 27 Minuten schrieb Memento: Hi. Ich hab grad nicht allzu viel Zeit, daher beschränke ich mich aufs SQL: Zum 1. SQL: "select distinct marke_bezeichnung from marke" macht doch das was du willst - oder? Warum der Join auf Fahrzeug? Du übergibst ja auch keine Parameter.. Gruß, Memento Das ist wohl egal in welcher Reihenfolge ich es schreibe. Funzt ja beides. Ich glaube zu wissen, dass ich den JOIN mache , weil in der Tabelle Fahrzeug die rstlichen Eigenschaften sind, dienoch mit verwendet werden. Die stehen nicht unter Marke.
30. November 20177 j Autor vor 26 Minuten schrieb PVoss: $sql = "Select DISTINCT modell_bezeichnung FROM fahrzeug Left JOIN modell ON modell.modell_id = fahrzeug.modell_id Where modell.modell_id = fahrzeug.modell_id AND marke_bezeichnung = '" . $marke ."'"; Von wo kommt denn das "marke_bezeichnung"? Du solltest dich noch zum Thema SQL-Injection einlesen: https://stackoverflow.com/questions/60174/how-can-i-prevent-sql-injection-in-php/60496#60496 marke_bezeichnung kommt von der Datenbank und vergleicht wird dies mit $marke (Die Marke, die vorher ausgewählt wurde. Lernen muss ich noch sehr viel ja Bearbeitet 30. November 20177 j von checkaline
30. November 20177 j Autor Danke erstmal an alle. Ich habe das Problem gefunden. Ich musste ein Join zwischen Marke und Fahrzeug noch zusätzlich machen, damit er überhaupt aud die Marke kommt, die vorher gewählt wurde.
30. November 20177 j vor 7 Minuten schrieb checkaline: Ich glaube zu wissen, dass ich den JOIN mache , weil in der Tabelle Fahrzeug die rstlichen Eigenschaften sind, dienoch mit verwendet werden. Die stehen nicht unter Marke. Du fragst doch nur "marke_bezeichnung" in deinem ersten SQL ab. Dazu brauchst du das Fahrzeug nicht. Wenn du noch weitere Attribute abfragst, benötigst du den Join eventuell. Übrigens: Bei einem Join auf 2 ID's musst du diese im WHERE nicht noch miteinander vergleichen. Das übernimmt der JOIN schon für dich. "select * from fahrzeug left join modell on modell.modell_id = fahrzeug.modell_id where modell.modell_id = fahrzeug.modell_id and ..." Das rot markierte kann man weglassen..
30. November 20177 j Unabhängig von den unnötigen Joins solltest du dich mal mit der Normalisierung und Indexierung einer Datenbank beschäftigen. Vielleicht kommst du ja dann von selber drauf, dass eine Filterung auf Strings keine besonders gute Idee ist.
30. November 20177 j Autor So sieht die Datenbank aus Ja muss ich mich beschäftigen allerdings muss ich Doku in 14 Tagen fertig haben.
30. November 20177 j Autor Unabhängig von den unnötigen Joins solltest du dich mal mit der Normalisierung und Indexierung einer Datenbank beschäftigen. Vielleicht kommst du ja dann von selber drauf, dass eine Filterung auf Strings keine besonders gute Idee ist.Meinst du weil ich die Bezeichnung filtere ?
30. November 20177 j Hallo in die Runde! Je nachdem, wie viel Logik du implementieren möchtest, ist das auch nicht ganz so trivial. Aus dem Baujahr ergeben sich z.B. bei Modellpflegen andere Folierungsflächen, die du irgendwie mappen musst. "Jahrhundert" ist da z.B. keine gute Eigenschaft. Entweder du fügst also noch ein Feld für "ModellVersion" hinzu, oder du nimmst innerhalb der Programmlogik ohne, dass der Benutzer es mitbekommt, eine Zuweisung von Baujahr zu Modell vor. Der Ford Galaxy sieht von 1995-2006 z.B. ganz anders aus als von 2006-2014. Der von 2015 sieht wieder anders aus. Wie löst du dieses Problem momentan? Gruß, Goulasz P.S.: Filtern auf Strings ist schon wegen des Risikos von Tippfehlern suboptimal. Lieber eine gute alte ComboBox mit "MarkenName" als Display und "MarkenID" als Value. Es sei denn du baust z.B. über die Levenshtein-Distanz(einer meiner Lieblinge^^) ein AutoCorrect bzw. eine Näherung ein. Aber davon gehe ich jetzt einfach mal nicht aus.
30. November 20177 j vor 36 Minuten schrieb checkaline: Meinst du weil ich die Bezeichnung filtere ? Ja, denn die Bezeichnung interessiert dich nicht. Außerdem ist es recht aufwendig auf Strings zu filtern. Die Bezeichnung ist nur Schmuck und wird höchstens an der Oberfläche angezeigt. Für gewöhnlich arbeitet man mit den IDs, auf denen dann ein Index liegt, damit die Datenbank effizienter arbeiten kann. Wenn du also die Marken haben willst, dann reicht: SELECT marke_id, marke_bezeichnung FROM marke Dann bekommst du schon alle Markenbezeichnungen. Ein Join ist unnötig und Ressourcenverschwendung, sofern der Optimierer dies nicht schon selbst erkennt und den Join entfernt. Beim zweiten SQL-Statement wird mir allerdings nicht ganz klar, wo bei dir der Unterschied zwischen Fahrzeug, Modell und Typ ist. In der Modell-Tabelle steht irgendwie nur die Bezeichnung aber alle anderen Informationen stehen in der Fahrzeug-Tabelle. Ich vermute mal, dass du die Fahrzeuge in unterschiedliche Modelle einteilen möchtest aber dann sind deine Tabellen falsch. EDIT: So langsam glaube ich zu verstehen, was du willst. Du möchtest alle Modellbezeichnungen von einer Automarke. Wenn wir dann die Marken ID haben, ist auch dies kein großes Problem: SELECT modell.modell_id, modell.modell_bezeichnung FROM modell INNER JOIN fahrzeug ON fahrzeug.modell_id = modell.modell_id WHERE fahrzeug.marke_id = $markeId Hätten wir nur die Markenbezeichnung, müssten wir tatsächlich einen weiteren Join hinzuziehen. Bearbeitet 30. November 20177 j von Whiz-zarD
30. November 20177 j @checkaline: Da Du hier von Projekt und Doku redest: Ist das dein Abschlußprojekt? Wenn ja, Du weißt aber dass Du für das Projekt eine Selbständigkeitserklärung abgibst?
30. November 20177 j Autor Ein Join ist unnötig und Ressourcenverschwendung, sofern der Optimierer dies nicht schon selbst erkennt und den Join entfernt. Beim zweiten SQL-Statement wird mir allerdings nicht ganz klar, wo bei dir der Unterschied zwischen Fahrzeug, Modell und Typ ist. In der Modell-Tabelle steht irgendwie nur die Bezeichnung aber alle anderen Informationen stehen in der Fahrzeug-Tabelle. Ich vermute mal, dass du die Fahrzeuge in unterschiedliche Modelle einteilen möchtest aber dann sind deine Tabellen falsch.Es sind 1800 Datensätze. Als Beispiel Audi gibt es 40x weil es davon verschiedene Modelle gibt. Also zb 10 x A110x A210x A3 10x A4Davon wieder Typen und davon Baujahr.So sind in der Fahrzeug Tabelle 1800 ids zu jeder id ist eine bestimmte Modell id , Typ id, Baujahr id usw
Erstelle ein Konto oder melde dich an, um einen Kommentar zu schreiben.