Unterschied SQL Abfrage in PHP und PhpMyADMIN?
WernerK
- datenbank
Hallo,
sicher gibt es eine ganz einfache Erklärung:
Folgender PHP Code für eine SQL Abfrage über zwei Tabellen.
$result = mysql_query("
SELECT
A.Name1, A.ElementsID
FROM
maptab A
WHERE A.TypeID = '$typeid'");
while($sql = mysql_fetch_array($result)){
$result_1 = mysql_query("
SELECT
NameXY
FROM
Tabelle2
WHERE TypeID = '$typeid' AND NameXY = '$sql[Name1]'");
$sql_1 = mysql_fetch_array($result_1);
echo "Der Name ist $sql[NameXY]";
}
Ich lese alo mit einer While Schleife zuerst Tabelle "maptab" aus. Mit dem Namen aus Spalte Name1 möchte ich dann wiederum alle Werte aus Tabelle 2 bekommen. Wenn ich es so mache wie im obigen Beispiel dann bekomme ich immer nur eine Zeile. Ich müsste also auch noch für den zweiten Select eine While Schleife machen.
Warum liefert mir aber PhpMyAdmin alle Ergebnisse wenn ich den gleichen 2. Select zum testen eingebe?
SELECT
NameXY
FROM
Tabelle2
WHERE TypeID = '87' AND NameXY = 'Gelb'
Macht da PhpMyAdmin intern eine While Schleife?
vielen Dank
Gruss
Werner
Hi WernerK!
Macht da PhpMyAdmin intern eine While Schleife?
Das steht im Manual: "Liefert ein Array das dem aktuellen Datensatz entspricht oder FALSE, wenn keine weiteren Datensätze vorliegen."
Quelle: http://de.php.net/manual/de/function.mysql-fetch-array.php
Also um deine Frage direkt zu beantworten: Ja.
MfG H☼psel
Macht da PhpMyAdmin intern eine While Schleife?
mal eine ganz andere frage: wozu ist die while-schleife bzw aus welcher (schlechten) doku hast du das?
ist eine unter-abfrage in diesem fall nicht wesentlich schlauer?
Hallo Werner,
allgemein ist Deine Abfrage etwas umständlich.
$result = mysql_query("
SELECT
A.Name1, A.ElementsID
FROM
maptab A
WHERE A.TypeID = '$typeid'");
Du musst das A gar nicht benutzen für diese Abfrage
SELECT Name1, ElementsID
FROM maptab
WHERE TypeID = '$typeid'
reicht vollkommen aus
für die erweiterte Abfrage:
Die folgende Abfrage sollte genau das darstellen was du hier samt schleife darstellen willst.
Mit Fremdschlüssel
$qry = mysql_query=("
SELECT tbl2.NameXY
FROM Tabelle2 AS tbl2, maptab AS A
WHERE tbl2.TypeID = '$typeid'
AND A.Name1 = tbl2.NameXY
");
Oder sicherer als Unterabfrage
$qry = mysql_query=("
SELECT NameXY
FROM Tabelle2
WHERE TypeID = '$typeid'
AND NameXY = (SELECT Name1 FROM maptab WHERE TypeID = '$typeid')
");
while ($res = mysql_fetch_object($qry)) {
echo "Der Name ist $res->NameXY<br>";
}
Ich hoffe, ich konnte Dir weiterhelfen.
Gruß,
Alex.
Hallo Alex,
allgemein ist Deine Abfrage etwas umständlich.
es ist ein typisches Vorgehen von Datenbankanfängern. Aus solchen Fehlern kann man jedoch lernen.
$result = mysql_query("
SELECT
A.Name1, A.ElementsID
FROM
maptab A
WHERE A.TypeID = '$typeid'");
Du musst das A gar nicht benutzen für diese Abfrage
SELECT Name1, ElementsID
FROM maptab
WHERE TypeID = '$typeid'
reicht vollkommen aus
Grundsätzlich spricht nichts dagegen Tabellenaliasnamen zu verwenden. Bei einer Abfrage über eine einzige Tabelle sind sie allerdings in der Tat überflüssig.
für die erweiterte Abfrage:
Die folgende Abfrage sollte genau das darstellen was du hier samt schleife darstellen willst.Mit Fremdschlüssel
$qry = mysql_query=("
SELECT tbl2.NameXY
FROM Tabelle2 AS tbl2, maptab AS A
WHERE tbl2.TypeID = '$typeid'
AND A.Name1 = tbl2.NameXY
");
Nein, diese Abfrage liefert nicht das gleiche wie die Kombination der Abfragen des Fragestellers. Er verlangt die gleiche TypeID in _beiden_ Tabellen. Das ist bei Deiner Abfrage nicht der Fall. Besser daher sauber mit einem INNER JOIN arbeiten:
SELECT
t2.NameXY -- das interessierende Ergebnis
FROM
maptab mt -- vernünftiger Aliasname
INNER JOIN -- die mit
Tabelle2 t2 -- Tabelle2 (Besser auf AS verzichten)
ON
mt.Name1 = t2.NameXY -- über gleiche Namen
AND -- und
mt.TypeID = t2.TypeID -- gleiche TypeID verknüpft ist
WHERE -- wobei nur Datensätze mit
mt.TypeID = <Wert> -- einer bestimmten TypeID interessieren
Oder sicherer als Unterabfrage
$qry = mysql_query=("
SELECT NameXY
FROM Tabelle2
WHERE TypeID = '$typeid'
AND NameXY = (SELECT Name1 FROM maptab WHERE TypeID = '$typeid')
");
Diese Abfrage ist in einer Sache sicherer: Da es TypeID-Werte gibt, für die die Unterabfrage mehr als einen Wert zurückliefert - was ja die Ausgangsfrage des OP ist - wird die Abfrage einfach einen Fehler produzieren und kein Ergebnis. Wenn schon ein Subselect, dann eher so:
SELECT -- Gib mir
NameXY -- die Namen
FROM -- aus
Tabelle2 -- Tabelle2
WHERE -- wobei in der Spalte
TypeID = <wert> -- TypeID nur ein bestimmter Wert vorkommen darf
AND -- und
NameXY IN ( -- Name XY in der Liste
SELECT -- der
Name1 -- Namen
FROM -- aus der Tabelle
maptab -- maptab
WHERE -- mit bestimmten (gleichen) Werten
TypeID = <wert> -- in der Spalte TypeID dieser Tabelle
) -- vorkommt
Es ist leicht ersichtlich, dass das Subselect hier deutlich komplizierter ist. Was die Ausführungsgeschwindigkeit betrifft, so sollte man EXPLAIN befragen.
Möchte der OP jeden Namen nur ein einziges Mal haben, dann böte sich das Schlüsselwort DISTINCT an.
Freundliche Grüße
Vinzenz