Zum Inhalt springen
View in the app

A better way to browse. Learn more.

Fachinformatiker.de

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

[MySQL] erster und letzter Tupel

Empfohlene Antworten

Veröffentlicht

Ich habe folgendes SQL Query:

SELECT T.threadid, FIRSTU.name AS creator,

MIN(DATE_FORMAT(FIRSTP.time, '%d.%m.%Y - %H:%i')) AS created, T.headline, LASTU.name AS lastuser,

MAX(DATE_FORMAT(LASTP.time, '%d.%m.%Y - %H:%i')) AS lastpost


FROM forum_threads T, forum_posts FIRSTP, forum_user FIRSTU, forum_posts LASTP, forum_user LASTU

WHERE T.forenid =1

AND T.threadid = FIRSTP.threadid

AND FIRSTU.userid = FIRSTP.userid

AND T.threadid = LASTP.threadid

AND LASTU.userid = LASTP.userid

GROUP BY threadid, headline

Es wird dazu benutzt um in einer PHP Seite (Forum) den ersten und letzten Post in einem Forumsthread zu ermitteln.

- ausgegangen wird von der Threadid (table forum_threads)

- nun wird zweimal (evtl. unnötig) die Tabelle forum_posts über threadid gejoined

- jetzt soll aus den post-Tabellen einmal der erste (order by time desc) und der letzte post rausgesucht werden

- jetzt wird 2mal die Tabelle forum_user auf die post-tabellen per userid gejoined um den jeweiligen username zu bekommen

Jetzt habe ich mittels GROUP BY geschafft immer das Feld time des ersten und letzten Posts anzuzeigen, der zur entsprechen headline threadid gehört.

Mein Problem ist: wie kann ich nun den Username an die rausgesuchte Zeit knüpfen (Min und Max)? Wenn möglich ohne Subselect.

Welche MySQL-Version?

Abgesehen davon, dass dein DB-Layout nicht ganz optimal ist, vielleicht geht's ja so, konnte allerdings nicht testen:


SELECT t.threadid, u.name AS creator, DATE_FORMAT(p.time, '%d.%m.%Y - %H:%i')) AS time, t.headline

FROM forum threads AS t, forum_posts AS p, forum_user AS u 

WHERE t.forenid = 1

AND p.threadid = t.threadid 

AND u.userid = p.userid 

HAVING p.time = MIN(p.time)

UNION

SELECT t.threadid, u.name AS creator, DATE_FORMAT(p.time, '%d.%m.%Y - %H:%i')) AS time, t.headline

FROM forum threads AS t, forum_posts AS p, forum_user AS u 

WHERE t.forenid = 1

AND p.threadid = t.threadid 

AND u.userid = p.userid 

HAVING p.time = MAX(p.time)

MySQL Version ist 4.1.7

Wieso ist das DB-Layout nicht optimal?

Bin für Verbesserungsvorschläge dankbar.

Nachdem ich ein paar kleine Tippfehler rausgenommen habe, bekomme ich den Fehler dass p.time in der HAVING-Klausel unbekannt ist. Funktioniert HAVING nicht nur mit GROUP BY?

Wäre das erhoffte Ergebnis deiner Lösung jeweils eine Zeile für ersten und letzten Post? Würde zwar gehen aber eigentlich hätte ich ja gerne alles in einer Zeile.

Ja, das war die zumindest "erhoffte" Lösung ;)...

Zum DB-Layout würde ich die Benutzer-ID und die Zeit der Threaderstellung noch mit in die Thread-Tabelle aufnehmen, dann musst Du nachher zur Bestimmung des letzten Post's nur noch einen JOIN auf die Post-Tabelle machen, und du hättest alles in einem Resultset...

HAVING sollte eigentlich auch ohne GROUP BY mit den Aggregatfunktionen funktionieren...

Das hatte ich auch mal überlegt. Wollte ich eigentlich vermeiden wegen Redundanz und so weiter aber ich habe hier ja gelernt dass man in der Praxis gerne mal Normalformen ignoriert um die Datenbank performanter zu gestalten.

Das könnte gehen, werde ich wohl auch machen aber dann ist mir immernoch nicht klar wie ich die Posttabelle joinen muss um das letzte Datum und die Userid bzw. den Namen zu erhalten.

Den ersten Post mal aussen vor gelassen, gibt dieses Query bei mir keine Zeile aus:


SELECT T.threadid, T.headline, P.userid, P.time

FROM forum_threads T, forum_posts P

WHERE T.threadid=1

AND T.threadid = P.threadid

HAVING P.time = MAX(P.time)

Vermutlich, weil sich das MAX(P.time) auf alle Tupel in P bezieht, diese Zeit allerdings nicht in dem Ausgewählten Forum/Thread vorkommt...

Ein ORDER BY P.time DESC LIMIT 1 wäre zu inperformant, oder?

Habe leider keine Erfahrung mit Perormancesachen bei Datenbanken.

Habe bisher nur mit winzigen Datenbanken zu Übungszwecken gearbeitet (Schule) und kann das nicht wirklich abschätzen. Die Seite in die das Forum eingebaut werden soll ist allerdings recht groß und gut besucht, weshalb das vielleicht zu Problemen führen könnte.

Das würde dann aber auch verhindern dass ich alle Threads in einem Forum selecten könnte. Denn eigentlich soll die Abfrage später mit WHERE forenid=? zum Einsatz kommen.

Wo ist eigentlich immer der EDIT-Button hin. Sobald ich den Thread einmal aktualisiere ist der weg. Das ist jedenfalls der Grund für meinen Doppelpost.

Ich habe mir gerade mal den phpBB Sourcecode angesehen. Entweder kenn die auch keine Lösung für mein Problem oder es ist performancetechnisch fürn A****. Die haben das jedenfalls so gelöst, dass sie in den Threads table 2 Felder für first und last_post_id eingefügt haben. Ich werde dass jetzt einfach genauso machen. Zum Einen müssen die phpBB Entwickler es ja wissen und zum Anderen habe ich keine Lust mehr darüber den Kopf zu zerbrechen.

Aber vielen Dank für deine Hilfe Monty.

Wos ist eigentlich immer der EDIT-Button hin. Sobald ich den Thread einmal aktualisieren ist der weg. Das ist jedenfalls der Grund für meinen Doppelpost.

Editieren geht nur die ersten 15 Minuten nachdem der Post erstellt wurde. Und ja, das ist so gewollt ;)

Na gut. Ich bin in einigen Foren unterwegs und da wird man für Doppelposts manchmal fast hingerichtet. ;)

Archiv

Dieses Thema wurde archiviert und kann nicht mehr beantwortet werden.

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.