2 SQL Abfragen kombinieren
Herbi
- php
Hallo zusammen,
ich möchte gerne zwei SQL Abfragen miteinander "kombinieren". Ehe ich lange in der Theorie erkläre, schildere ich lieber das konkrete Beispiel. Ich habe eine Datenbank mit diversen Einträgen. Es sollen zunächst einmal die 5 neuesten Einträge herausgesucht werden:
SELECT * FROM tabelle ORDER BY datum DESC LIMIT 5
Dann möchte ich, dass alle Einträge, die in der Spalte "option" ein "ja" zu stehen haben, angezeigt werden.
SELECT * FROM tabelle WHERE option='ja' ORDER BY datum DESC
Soweit ist alles klar. Ich möchte es nun aber hinkriegen, dass sowohl die 5 neuesten Einträge (s. Abfrage 1), als auch *alle* Einträge mit option = ja ausgegeben werden, und zwar innerhalb einer SQL-Abfrage.
Kann mir jemand helfen, wie ich dafür vorzugehen habe?
Vielen dank im Vorraus,
Herbi
Hallo,
welches Datenbankmanagementsystem in welcher Version verwendest Du?
Es sollen zunächst einmal die 5 neuesten Einträge herausgesucht werden:
SELECT * FROM tabelle ORDER BY datum DESC LIMIT 5
Ich vermute MySQL.
Dann möchte ich, dass alle Einträge, die in der Spalte "option" ein "ja" zu stehen haben, angezeigt werden.
SELECT * FROM tabelle WHERE option='ja' ORDER BY datum DESC
Ich möchte es nun aber hinkriegen, dass sowohl die 5 neuesten Einträge (s. Abfrage 1), als auch *alle* Einträge mit option = ja ausgegeben werden, und zwar innerhalb einer SQL-Abfrage.
UNION sollte Dir helfen. Beachte die Hinweise, wie Du ein Teilergebnis limitierst und wie das Gesamtergebnis sortiert wird.
Was ist mit den Einträgen unter den neuesten Einträgen, die in der Spalte 'option' den Wert 'ja' haben?
Freundliche Grüße
Vinzenz
Hallo Vinzenz,
welches Datenbankmanagementsystem in welcher Version verwendest Du?
Ich vermute MySQL.
Richtig. MySQL-Client-Version: 4.1.13
UNION sollte Dir helfen. Beachte die Hinweise, wie Du ein Teilergebnis limitierst und wie das Gesamtergebnis sortiert wird.
Das scheint der richtige Weg zu sein. Ich bekomme mit UNION alle Befehle ausgegeben. Es hapert nur an der richtigen Sortierung. Auf der verlinkten Seite steht, man müsse das so machen:
(SQL Abfrage 1) UNION (SQL Abfrage 2) ORDER BY xyz
Das habe ich mal so versucht, aber sobald ich das ORDER BY hinter die 2. SQL Abfrage nach der schließenden Klammer setze, erhalte ich null Ergebnisse. Packe ich das ORDER BY in die Klammern klappt alles, aber natürlich sind dadurch beide Abfragen nur jeweils für sich sortiert.
So siehts derzeit bei mir aus
(SELECT * FROM tabelle1, tabelle2 WHERE tabelle1.status='on' && tabelle1.gueltig > ".$cfg['time']." && tabelle1.id = tabelle2.id && tabelle1.option= 'ja')
UNION
(SELECT * FROM tabelle1, tabelle2 WHERE tabelle1.status='on' && tabelle1.gueltig > ".$cfg['time']." && tabelle1.id = tabelle2.id ORDER BY tabelle1.datum DESC LIMIT 5)
ORDER BY tabelle1.datum DESC
Ok ich glaube es liegt daran:
"This kind of ORDER BY cannot use column references that include a table name (that is, names in tbl_name.col_name format). Instead, provide a column alias in the first SELECT statement and refer to the alias in the ORDER BY. (Alternatively, refer to the column in the ORDER BY using its column position. However, use of column positions is deprecated.)"
Allerdings versteh ich nicht so recht was mit der Aussage "provide a column alias in the first SELECT statement and refer to the alias in the ORDER BY" gemeint ist. Kann mir das vielleicht jemand anhand meines Beispiels (einen Beitrag höher) erläutern?
Ich hab zwar hier SQL Alias rausgefunden, wie es theoretisch gehen müsste, aber meine Versuche das zu übertragen haben nicht funktioniert... :-(
Vielen Dank im Vorraus,
Herbi
Hello,
das Handbuch sollte dir da eigentlich direkt zeigen, wie es falsch und richtig aussieht:
---
Ferner muss, wenn einer zu sortierenden Spalte ein Alias zugewiesen wird, die ORDER BY-Klausel den Alias und nicht den Spaltennamen referenzieren. Die erste der folgenden Anweisungen funktioniert – im Gegensatz zur zweiten, die mit dem Fehler Unknown column 'a' in 'order clause' fehlschlägt:
---
Falsch:
(SELECT a AS b FROM t) UNION (SELECT ...) ORDER BY a;
du kannst nicht nach "a" sortieren, da es außerhalb des UNION nicht mehr adressiert werden kann
Richtig:
(SELECT a AS b FROM t) UNION (SELECT ...) ORDER BY b;
Du vergibst für die Spalte a einen Aliasnamen "b", nach dem du nun sortieren kannst.
Ich vermute zudem, auch wenn nicht explizit genannt und von der Nachvollziehbarkeit her ein Alptraum, dass du auch den Index der Sortierspalte angeben kannst, also etwa ORDER BY 1
MfG
Rouven
Hallo Rouven,
danke für Deine Mühen. Soweit hatte ich es auch verstanden. ORDER BY tabelle1.datum funktioniert nicht, weil ich tabelle1.datum erst ein column alias zuweisen muss.
Mein Problem lautet: Wie weise ich in diesem Beispiel:
(SELECT * FROM tabelle1, tabelle2 WHERE tabelle1.status='on' && tabelle1.gueltig > ".$cfg['time']." && tabelle1.id = tabelle2.id && tabelle1.option= 'ja')
tabelle1.datum ein column alias, z.B. "datum" zu?
Hello,
(SELECT * FROM tabelle1, tabelle2 WHERE tabelle1.status='on' && tabelle1.gueltig > ".$cfg['time']." && tabelle1.id = tabelle2.id && tabelle1.option= 'ja')
oha, nun ja.
1.
Ich halte es ja schon für unklug, bei einer einzelnen Tabelle SELECT * zu schreiben, aber bei einem JOIN mit SELECT * zu arbeiten verdoppelt ja gleich die Wahrscheinlichkeit, unerwartete Spalten zu kriegen. Wir haben die Diskussion hier öfter, ob SELECT * jetzt schlimm ist oder nicht. Im Fall von UNION kommt dem eine gewisse Brisanz zu denn das UNION ist darauf angewiesen, dass alle Abfragen exakt die gleichen Spalten in exakt der gleichen Reihenfolge liefern.
Wenn du die Spalten also explizit auflistest, verringerst du das Risiko von Problemen und bringst dich gleichzeitig deinem Alias näher:
SELECT tabelle1.spalte1, tabelle1.spalte2, tabelle2.spalte1, tabelle2.spalte2... FROM tabelle1, tabelle2 WHERE tabelle1.status='on' && tabelle1.gueltig > ".$cfg['time']." && tabelle1.id = tabelle2.id && tabelle1.option= 'ja'
2.
Die Syntax "tabelle1, tabelle2" halte ich darüberhinaus auch für unglücklich. Wenn du mehr wissen willst, dann lege ich dir z.B. meinen Artikel zu JOINs und Vinzenz Fortsetzung Fortgeschrittene Joins ans Herz.
MfG
Rouven
Hallo Rouven,
danke für Deine ausführliche Antwort. Ich habe das * jetzt entfernt und die Spalten einzeln aufgelistet, dabei hat auch das Zuweisen eines alias funktioniert und nun klappt es auch mit der richtigen Sortierung des UNION Befehls.
Viele Grüße,
Herbi
Hello,
Das habe ich mal so versucht, aber sobald ich das ORDER BY hinter die 2. SQL Abfrage nach der schließenden Klammer setze, erhalte ich null Ergebnisse.
ähm, dann hast du einen Fehler in deinem PHP-Skript. Die Sortierung kann nur greifen oder nicht - du hast demnach einen von MySQL angekreideten Syntaxfehler ignoriert, kann das sein?
MfG
Rouven
Hi Rouven,
ähm, dann hast du einen Fehler in deinem PHP-Skript. Die Sortierung kann nur greifen oder nicht - du hast demnach einen von MySQL angekreideten Syntaxfehler ignoriert, kann das sein?
Ich vermuete mal der Fehler liegt eher hier begründet:
http://forum.de.selfhtml.org/?t=182699&m=1209227
Gruß, Herbi
Hello,
Ich vermuete mal der Fehler liegt eher hier begründet:
ja, siehe auch mein Kommentar da, aber nur weil du ein ORDER BY angibst, liefert eine Abfrage nicht nichts mehr zurück. Sie liefert die selbe Datensatzmenge wie vorher, nur halt anders sortiert, oder halt nicht, wie bei MySQL+UNION+ORDER BY ohne LIMIT. Wenn bei dir Ergebnisse nicht vorhanden sind, dann ist eher davon auszugehen, dass du den Fehler der Art "unknown column a in ..." ignoriert hast.
MfG
Rouven