Themen im Forum sortieren: SELECT Frage

Hallo Leute,

wiedereinmal stehe ich vor einem Problem. Ich bin gerade dabei ein Forum zu machen, und möchte gerne die Themen sortieren (sprich da wo der letzte Eintrag war, nach ganz oben)

Folgende Infos habe ich da für euch:

Tabelle forum_thema:

  • forum_thema_id
  • forum_id
    -…usw

Tabelle forum_eintrag:

  • forum_thema_id
  • eintrag_time
  • thema_id
    -…usw

Jeder Eintrag ist einem Thema zugewiesen, ich möchte nun die id geordnet nach den neuesten Themen selektieren. Die Forum ID wird von php eingegeben, und ist jetzt zum Beispiel 1

Meine derzeite Lösung sieht so aus:

SELECT forum_thema_id
FROM forum_thema, forum_eintrag 
WHERE forum_thema.forum_id=1 AND forum_thema.forum_thema_id=forum_eintrag.thema_id
ORDER BY eintrag_time DESC

Und sobald ich ein group by dazu gebe, funktioniert es nicht mehr. (eh klar)

In welcher Reihenfolge wird das eigentlich abgearbeitet.

Ich denke mir mal wie folgt:

  • Es wird jede Tabelle mit jeder verknüpft (auch jede spalte wird noch behalten
  • Dann wird mit where einiges weg geschmissen
  • Dann wird das gemacht was geben als erster steht, order by oder group?
  • dann werden die selektiert die nach SELECT stehen.

Stimmt wahrscheinlich nicht, aber ich wollte euch einmal erklären worauf ich mit meiner Frage hinaus will.

Bitte um Infos oder Links.

Danke im voraus
Darian

Hallo,

wäre fein wenn mir hier noch jemand helfen könnte, das Problem habe ich bis jetzt leider noch immer nicht gelöst.

Wenn ich was schlecht geschrieben habe, oder ihr Fragen habt, nur her damit.

Bitte um eure Hilfe. Würde mich allgemein und auch für die Zukunft interessieren wie man sowas macht.

lg Darian

Wo ist oben im Internet?

Folgende Infos habe ich da für euch:

Tabelle forum_thema:

  • forum_thema_id
  • forum_id
    -…usw

Tabelle forum_eintrag:

  • forum_thema_id
  • eintrag_time
  • thema_id
    -…usw

Jeder Eintrag ist einem Thema zugewiesen, ich möchte nun die id geordnet nach den neuesten Themen selektieren. Die Forum ID wird von php eingegeben, und ist jetzt zum Beispiel 1

Ich bin mir nicht sicher, dich richtig zu parsen. Falls ja: du brauchst doch nur nach eintrag_time zu sortieren.

Meine derzeite Lösung sieht so aus:

SELECT forum_thema_id
FROM forum_thema, forum_eintrag
WHERE forum_thema.forum_id=1 AND forum_thema.forum_thema_id=forum_eintrag.thema_id
ORDER BY eintrag_time DESC

>
> Und sobald ich ein group by dazu gebe, funktioniert es nicht mehr. (eh klar)

Was genau willst Du denn gruppieren?

> In welcher Reihenfolge wird das eigentlich abgearbeitet.
>
> Ich denke mir mal wie folgt:
>
> - Es wird jede Tabelle mit jeder verknüpft (auch jede spalte wird noch behalten
> - Dann wird mit where einiges weg geschmissen
> - Dann wird das gemacht was geben als erster steht, order by oder group?
> - dann werden die selektiert die nach SELECT stehen.

Auch nach 3 mal lesen und 5 Bier hab ich Probleme, da einen Sinn zu erkennen. Vermutlich fehlt Bier.

> Stimmt wahrscheinlich nicht, aber ich wollte euch einmal erklären worauf ich mit meiner Frage hinaus will.
>
> Bitte um Infos oder Links.
>
> Danke im voraus
> Darian

Es wäre u.U. hilfreich, Du würdest mal bleistifthaft Deine Tabellen mit Content als SQL hier nennen und dann auch das, was Du Dir erhoffst. Alternativ mir einen Kasten Radeberger vors Haus stellen.
\
\
Andreas

Danke einmal für deine Antwort, muß mir bei einigen Sachen mal genauer darüber nachdenken, und werde später noch darauf antworten.

Oben genau wie so:

  • oben
  • weiter unten
  • noch weiter unten
  • ganz weit unten

Ok, klären wir bitte erst einmal wie das bei den SELECT funktioniert.

Wenn ich von zwei Tabellen was selektiere, wird erst einmal alles mit allem verknüpft.

Dann wird das WHERE dazu benutzt um einige Ergebnisse weg zu streichen.

Wie funktioniert das dann weiter? bzw stimmt das so?

lg Darian

P.S.: Würde mir sicher helfen wenn ich genauer wüsste wie das im Hintergrund abläuft…

Tue dies.

Ok, klären wir bitte erst einmal wie das bei den SELECT funktioniert.

Wenn ich von zwei Tabellen was selektiere, wird erst einmal alles mit allem verknüpft.

Depends. Nur bei einem CROSS-JOIN. Den will man einklich nur recht selten.
Die JOIN-Typen findest Du hier erklärt:
http://v.hdm-stuttgart.de/~riekert/lehre/db-kelz/chap7.htm


Dann wird das WHERE dazu benutzt um einige Ergebnisse weg zu streichen.

Wie funktioniert das dann weiter? bzw stimmt das so?

Man kann sich anschauen, wie der Planner vorgeht. Der magische Spruch lautet: EXPLAIN.

P.S.: Würde mir sicher helfen wenn ich genauer wüsste wie das im Hintergrund abläuft…

Um die Details muß man sich nicht allzu oft kümmern, ein EXPLAIN, evtl. mit ANALYSE kombiniert, liefert genug Wissen, wie was abläuft.


Andreas

Hallo Leute,

das mit EXPLAIN ist schon eine feine Sache. Leider habe ich Probleme da genaueres heraus zu lesen (sprich ich verstehe nicht so ganz was man dann da raus sieht)

Bericht erstellen kann ich nicht (=> Berichtdatenbank nicht installiert)

Gibt es dazu auch irgendwo genauere Infos?

lg und danke
Darian

Bahnhof. Kippe das, was EXPLAIN liefert, mal hier rein. Zwischen CODE-Tags. Was Du mit Bericht erstellen bzw. Berichtdatenbank meinst, weiß ich nicht.

Ansonsten:
“explaining explain” in Google kippen und das PDF lesen. 1. Treffer.

Andreas

Schaut hier, das kommt raus, verstehe es aber nicht so wirklich…

QUERY PLAN

Sort  (cost=40.62..40.64 rows=6 width=12)

  Sort Key: forum_eintrag.eintrag_time

  ->  Hash Join  (cost=16.38..40.54 rows=6 width=12)

        Hash Cond: (forum_eintrag.thema_id = forum_thema.forum_thema_id)

        ->  Seq Scan on forum_eintrag  (cost=0.00..19.40 rows=940 width=12)

        ->  Hash  (cost=16.38..16.38 rows=3 width=4)

              ->  Seq Scan on forum_thema  (cost=0.00..16.38 rows=3 width=4)

                    Filter: (forum_id = 1)
 

lg Darian

Ohne das SELECT dazu ist das latürnich auch schwer zu verstehen. Was man sieht, ist, daß da auf forum_thema.forum_id offensichtlich kein Index ist. Besser wäre, man hätte das SELECT dazu und, Du hättest EXPLAIN ANALYSE gerufen. Das bringt nicht nur Schätzungen, sondern auch reale Kosten ans Tageslicht.

Andreas

Ok, dann probieren wir es einmal so…

Befehl:

EXPLAIN ANALYSE SELECT forum_thema_id
FROM forum_thema, forum_eintrag 
WHERE forum_thema.forum_id=1 AND forum_thema.forum_thema_id=forum_eintrag.thema_id
ORDER BY eintrag_time DESC

Ergebnis:

QUERY PLAN

Sort  (cost=40.62..40.64 rows=6 width=12) (actual time=0.211..0.217 rows=26 loops=1)

  Sort Key: forum_eintrag.eintrag_time

  ->  Hash Join  (cost=16.38..40.54 rows=6 width=12) (actual time=0.084..0.111 rows=26 loops=1)

        Hash Cond: (forum_eintrag.thema_id = forum_thema.forum_thema_id)

        ->  Seq Scan on forum_eintrag  (cost=0.00..19.40 rows=940 width=12) (actual time=0.010..0.017 rows=35 loops=1)

        ->  Hash  (cost=16.38..16.38 rows=3 width=4) (actual time=0.030..0.030 rows=13 loops=1)

              ->  Seq Scan on forum_thema  (cost=0.00..16.38 rows=3 width=4) (actual time=0.014..0.020 rows=13 loops=1)

                    Filter: (forum_id = 1) 

Bin schon gespannt was da jetzt dabei raus kommt…

Hättest du bitte auch Infos diesbezüglich auf deutsch…?

lg Darian

Tja, z.B., daß die Statistiken schlecht sind. Geschätze 940 zu realen 35 rows deuten auf jede menge dead tuples hin, Du solltest Dir mal VACUUM ANALYSE anschauen

Hättest du bitte auch Infos diesbezüglich auf deutsch…?

Hä? Möchtest Du, das ich SQL-Befehle eindeutsche?
Oder meinst Du eine Erklärung für EXPLAIN in deutsch? Falls ja, google mal nach diesen Begriffen:

Susanne Ebrecht EXPLAIN freex

Ich bin grad zu faul und finde auch den Link nicht gleich, aber Miracee^WSusanne hat in der FreeX vor einigen Wochen einen Grundlagenartikel dazu geschrieben. In deutsch.


Andreas

http://www.cul.de/data/freex22007pr.pdf

Andreas

Hallo,

ich denke jetzt dürfte es besser aussehen, habe mal das mit dem VACUUM ANALYSE gemacht…

QUERY PLAN

Sort  (cost=17.93..17.93 rows=1 width=12) (actual time=0.222..0.228 rows=26 loops=1)

  Sort Key: forum_eintrag.eintrag_time

  ->  Hash Join  (cost=16.38..17.92 rows=1 width=12) (actual time=0.083..0.106 rows=26 loops=1)

        Hash Cond: (forum_eintrag.thema_id = forum_thema.forum_thema_id)

        ->  Seq Scan on forum_eintrag  (cost=0.00..1.35 rows=35 width=12) (actual time=0.008..0.013 rows=35 loops=1)

        ->  Hash  (cost=16.38..16.38 rows=3 width=4) (actual time=0.030..0.030 rows=13 loops=1)

              ->  Seq Scan on forum_thema  (cost=0.00..16.38 rows=3 width=4) (actual time=0.013..0.019 rows=13 loops=1)

                    Filter: (forum_id = 1)

Total runtime: 0.309 ms

Wollte nur allgemein Infos diesbezüglich auf deutsch. EXPLAIN, EXPLAIN ANALYSE,…usw

Ok, wie ich mein SELECT mache weiß ich bis jetzt noch immer nicht…werde mal genauere Infos hier herein geben.

lg Darian

Bezieht sich diese Bemerkung auf Deinen ersten Beitrag hier im Thread und der dort geschilderten Tabellenstruktur?

Falls ja:

test=*# select * from forum_eintrag;
 forum_thema_id |        eintrag_time        | thema_id |   inhalt
----------------+----------------------------+----------+-------------
              1 | 2007-04-21 12:24:11.027365 |        1 | bla fasel
              1 | 2007-04-21 12:24:29.975524 |        1 | bla fasel 2
              1 | 2007-04-21 12:24:36.580611 |        1 | bla fasel 3
              2 | 2007-04-21 12:24:57.668316 |        1 | foo bar
              1 | 2007-04-21 12:25:03.487877 |        1 | bla fasel 4
              2 | 2007-04-21 12:25:10.805913 |        1 | foo bar 2
(6 rows)

test=*# select * from forum_eintrag 
   where (forum_thema_id, eintrag_time) in (
      select forum_thema_id, max(eintrag_time) from forum_eintrag group by forum_thema_id);
 forum_thema_id |        eintrag_time        | thema_id |   inhalt
----------------+----------------------------+----------+-------------
              1 | 2007-04-21 12:25:03.487877 |        1 | bla fasel 4
              2 | 2007-04-21 12:25:10.805913 |        1 | foo bar 2
(2 rows)

Hab jetzt mal was pöses gemacht: select *. Es wäre vielleicht sinnvoll, jedem Eintrag eine eindeutige ID (via SERIAL) zu verpassen, dann wäre der JOIN wohl einfacher. Die passenden Indexe zu finden überlasse ich Dir zur Übung…



Andreas

Hallo, dabei habe ich natürlich wieder ein paar Fragen :frowning: wie soll es anders sein)

  1. Die Spalte forum_thema_id gibt es nicht in dieser Tabelle, da heißt sie komischerweise nur forum_id (ich weiß ich weiß, und wenn ich das ändere, bekomme ich sogar ein Ergebnis) Hast du das so gemeint?

  2. Das ist ja ein Intersection? Du arbeitest aber immer nur mit einer Tabelle, braucht man dazu nicht zwei? (immer nur die forum_eintrag)

  3. irgendwo muß ja reingeschreiben die forum_id eingegbeen sein. Sprich die Themen in diesem Forum sollen nur selektiert werden…?

  4. Ach ja, noch was, habe nicht so wirklich gefunden was das max macht. Was tut es den? (nehme mal an er selektiert den höchsten Wert, oder?)

Bitte wie immer um ein paar Hilfen…

lg Darian

Seufz.

  1. Die Spalte forum_thema_id gibt es nicht in dieser Tabelle, da heißt sie komischerweise nur forum_id (ich weiß ich weiß, und wenn ich das ändere, bekomme ich sogar ein Ergebnis) Hast du das so gemeint?

Ähm, vermutlich.

  1. Das ist ja ein Intersection? Du arbeitest aber immer nur mit einer Tabelle, braucht man dazu nicht zwei? (immer nur die forum_eintrag)

Es gibt eine Unterabfrage. Diese liefert eine Tabelle. Da waren es schon zwei.

  1. irgendwo muß ja reingeschreiben die forum_id eingegbeen sein. Sprich die Themen in diesem Forum sollen nur selektiert werden…?

Hä?

  1. Ach ja, noch was, habe nicht so wirklich gefunden was das max macht. Was tut es den? (nehme mal an er selektiert den höchsten Wert, oder?)

Paul-Panzer-Mode: Rrrrrichtig.

Andreas

Hallo Leute,

habe nun vorhin die Homepage schon fast fertig, bis auf das selbe Problem wie wir es hier schon begonnen haben.

Ich habe nun ein Bild gemacht, vielleicht kann mir dann wer weiter helfen.

Vielleicht kann mir jetzt jemand weiter helfen, eigentlich sieht es ja gar nicht so kompliziert aus oder?

mfg und danke im voraus
Darian