zwei Abfragen in einer MySQL Abfrage?
Bernd
- mysqli
- php
Hallo,
ist es möglich in einer MYSQL Abfrage direkt zwei Abfragen zu tätigen? In meiner ersten hole ich alle Projekte die sich in der Datenbank befinden
$sql_Projekte = "SELECT p_titel, p_von, p_bis FROM projekte ";
$statement_Projekte = $mysqli->prepare($sql_Projekte);
$statement_Projekte->execute();
$result_Projekte = $statement_Projekte->get_result();
Jetzt habe ich noch eine zweite Tabelle mit dem Namen projektbilder. Wenn dort Bilder von einem Projekt hinterlegt sind, nur dann sollen die Projekte auch angezeigt mit dem Hinweis, es sind xxx Bilder vorhanden.
Ist dieses irgendwie möglich?
Hallo Bernd,
füge einen Subselect hinzu.
SELECT p_titel, p_von, p_bis, (SUBSELECT) as anz_bilder
FROM projekte
Verstehensenergiebooster: Finde einen Select, der Dir für ein Projekt die Anzahl der dafür vorhandenen Bilder bestimmt, und den Du für SUBSELECT einsetzen kannst.
Rolf
Hallo,
ich dachte er ich komme so weiter
SELECT p_code, p_titel, p_von, p_bis (SELECT COUNT(*) FROM projektbilder WHERE bild_refID = p_code ) as anz_bilder FROM projekte
aber da erhalte ich in phpMyAdmin eine Fehlermeldung
#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'SELECT COUNT(*) FROM projektbilder WHERE bild_refID = p_code ) as anz_bilder FRO' at line 1
Hallo Bernd,
stimmt da hat Du was geschrieben das nicht der SQL Syntax entspricht auf sowas muss man wenn man keine Meldung haben will schon achten.
Den gleichen Fehler, den Du in deinem Statement hast, habe ich in vorstehendem Satz gemacht. Mehrfach 😉
Rolf
Jetzt habe ich es versucht
SELECT * FROM projekte P
WHERE NOT EXISTS (
SELECT * FROM projektbilder PB
WHERE EXISTS (
SELECT * FROM projekte P1
WHERE P1.p_code = PB.bild_refID
AND P1.p_code = P.p_code))
Geht wohl auch nicht, ich kann mich nicht mehr in phpMyAdmin einloggen. Super. Ich mach es wohl doch lieber mit einem zweiten SQL.
Ich habe es
SELECT a.p_code, `p_id`, `p_titel`
FROM projekte AS a
LEFT JOIN projektbilder AS b ON a.p_code = b.bild_refID
WHERE b.bild_refID IS NOT NULL GROUP by p_id
Hallo Bernd,
okay, so bekommst Du alle Projekte, die Bilder haben. Die Anzahl fehlt.
Aber warum jetzt ein neuer Ansatz? Du warst doch schon fast am Ziel. Es fehlte nur ein dummes, kleines Komma. Ich dachte, mein kommafreier Satz hätte Dich drauf gebracht.
SELECT p_code, p_titel, p_von, p_bis (SELECT COUNT(*) FROM projektbilder WHERE bild_refID = p_code ) as anz_bilder FROM projekte
Was inhaltlich noch fehlt, ist die Begrenzung auf Projekte mit Bildern.
MYSQL erlaubt Dinge, die sonst nirgends gehen. Darum weiß ich nicht, ob man eine Subselect-Spalte in einer WHERE Bedingung verwenden darf. MS SQL Server erlaubt es nicht. Also dies hier:
SELECT p_code, p_titel, p_von, p_bis,
(SELECT COUNT(*) FROM projektbilder
WHERE bild_refID = p_code ) as anz_bilder
FROM projekte
WHERE anzahl > 0
Wenn MySQL das erlaubt, wäre es das, was Du brauchst. Denke ich.
Wenn nicht - normgerechteres SQL sähe so aus:
SELECT *
FROM (SELECT p_code, p_titel, p_von, p_bis,
(SELECT COUNT(*) FROM projektbilder
WHERE bild_refID = p_code ) as anz_bilder
FROM projekte) X
WHERE anzahl > 0
Alternativ mit einem Inner Join, das ist das gleiche wie ein LEFT JOIN bei dem man abfragt ob keine Sätze zugemischt wurden:
SELECT p_code, p_titel, p_von, p_bis, COUNT(*)
FROM projekte P JOIN projektbilder B ON B.bild_refID = P.p_code
GROUP BY p_code, p_titel, p_von, p_bis
In MYSQL reicht es, p_code ins GROUP BY zu schreiben, sofern es zu einem p_code nur einen Satz in der projekte-Tabelle gibt. Normgerechtere DBs verlangen, dass alle SELECT-Spalten, die nicht aggregiert werden, im GROUP BY gelistet sind und damit auch an der Gruppierung teilnehmen (was bei eindeutigem p_code zum gleichen Ergebnis führt).
Rolf
Hallo,
vielen Dank für deine Erklärung. Ich habe mich für diese Variante entschieden
SELECT *
FROM (SELECT p_code, p_titel, p_von, p_bis,
(SELECT COUNT(*) FROM projektbilder
WHERE bild_refID = p_code ) as anz_bilder
FROM projekte) X
WHERE anzahl > 0
Allerdings bei WHERE nicht anzahl sondern anz_bilder ;)
MYSQL erlaubt Dinge, die sonst nirgends gehen
Was meinst du damit?
Dann hätte ich noch eine Frage. Ist es möglich Bilder sortieren zu lassen? Erst alle 200x150 und danach mit ein wenig Abstand 200x267
Hallo Bernd,
Bilder sortieren kannst Du nicht, aber die Datenbanksätze, die die Informationen zum Bild enthalten, kann man nach der Höhe des Bildes sortieren. Das kannst Du im SQL machen oder nachgelagert im PHP.
Das ist dann aber eine andere Query. In der bisher diskutierten Abfrage ging es um die Anzahl der Bilder pro Projekt.
Der kleine Abstand ist aber keine Frage des SQL, sondern des PHP. Wenn Du das HTML für die Bilder erzeugst, kannst Du abfragen ob sich von SQL-Row zu SQL-Row die Höhe ändert, und dann via HTML Abstand erzeugen (z.B. durch Hinzufügen einer class neue-höhe
, die per CSS Regel einen größeren margin-top erzeugt). Alternativ könnte man die Bilder, die gleiche Höhe haben, auch in einen eigenen HTML Container einschließen (div, section, ul, je nach gewünschter Semantik) und durch das Styling des Containers den Extraabstand erzeugen. Wenn der Container eine flexbox mit row-wrap ist, könntest Du damit die Bilder auch in Zeilen anordnen und bei Höhenwechsel einen Umbruch produzieren. Das Spektrum der Möglichkeiten ist breit.
Rolf
Moin,
Sag ihm doch bitte das einfach ein Komma fehlt(e). und ein Count(*) würde ich persönlich auch nie notieren.
Gruß Bobby
Hallo bobby,
einen Kommafehler selbst zu finden ist deutlich lehrreicher. Ich habe Bernd hier schon so viel vorgekaut, da muss er auch selbst mal knabbern 😉. Nachdem er einen anderen Weg eingeschlagen hatte, habe ich ihm das mit dem Komma ja auch erzählt.
Mal abgesehen von unterschiedlichen Vorstellungen zur Wissensvermittlung - was spricht gegen COUNT(*), um etwas zu zählen? Was ist dein persönlicher besserer Ansatz?
Rolf
Moin,
ok. Ich nehms zurück. Ich hätte ein indiziertes Feld genommen, was aber durch dne Abfragetyp "SIMPLE" keinen Unterschied macht.
Sorry
Gruß Bobby
Hallo bobby,
natürlich hast Du recht mit dem Hinweis, dass man in einem Subselect wie diesem
SELECT COUNT(*) FROM projektbilder WHERE bild_refID = p_code
darauf achten muss, dass die im WHERE verwendete Spalte (bild_refID) indexiert ist. Andernfalls hat man einen Subselect mit Tablescan und der Festplattenhersteller freut sich.
Rolf