Jump to content
  • 0

Bräuchte Hilfe bei einer SQL Anweisung inkl. php

Frage

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 von checkaline

Diesen Beitrag teilen


Link zum Beitrag
Auf anderen Seiten teilen

14 Antworten auf diese Frage

Empfohlene Beiträge

  • 0

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 von Memento

Diesen Beitrag teilen


Link zum Beitrag
Auf anderen Seiten teilen
  • 0
 $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

Diesen Beitrag teilen


Link zum Beitrag
Auf anderen Seiten teilen
  • 0

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 :goulasz: 

 

 

 

Diesen Beitrag teilen


Link zum Beitrag
Auf anderen Seiten teilen
  • 0
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.

Diesen Beitrag teilen


Link zum Beitrag
Auf anderen Seiten teilen
  • 0
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 von checkaline

Diesen Beitrag teilen


Link zum Beitrag
Auf anderen Seiten teilen
  • 0
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..

Diesen Beitrag teilen


Link zum Beitrag
Auf anderen Seiten teilen
  • 0
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 ?

Diesen Beitrag teilen


Link zum Beitrag
Auf anderen Seiten teilen
  • 0

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 :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.

 

Diesen Beitrag teilen


Link zum Beitrag
Auf anderen Seiten teilen
  • 0
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 von Whiz-zarD

Diesen Beitrag teilen


Link zum Beitrag
Auf anderen Seiten teilen
  • 0
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 A1
10x A2
10x A3
10x A4

Davon 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

Diesen Beitrag teilen


Link zum Beitrag
Auf anderen Seiten teilen
Gast
Du kommentierst als Gast. Wenn du bereits einen Account hast kannst du dich hier anmelden.
Diese Frage beantworten...

×   Du hast formatierten Text eingefügt.   Formatierung jetzt entfernen

  Only 75 emoticons maximum are allowed.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Clear editor

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.


×