WCM Forum

WCM Forum (http://www.wcm.at/forum/index.php)
-   Programmierung (http://www.wcm.at/forum/forumdisplay.php?f=17)
-   -   [SQL] ORDER Problem (http://www.wcm.at/forum/showthread.php?t=149713)

Potassium 07.11.2004 20:16

[SQL] ORDER Problem
 
PHP-Code:

        $query SQL("SELECT T.*,P.Post_Time FROM ".TABLE_TOPICS." T, ".TABLE_POSTS." P WHERE T.Topic_Group = '".$Group_ID."' AND T.Topic_Index_Show = '1' AND P.Post_Topic_ID = T.Topic_ID GROUP BY T.Topic_Date ORDER BY P.Post_Time DESC,T.Topic_Date DESC, T.Topic_Sticky ASC",__FILE__,__LINE__); 

ich hab also 2 tables. eine mit themen und eine mit beiträgen (antworten)
nun sollen die jüngsten themen als oberstes stehen. also entweder die als letztes geschrieben wurden oder auf die als letztes geantwortet wurde. und dann gibt es noch die option "sticky" die is entweder 0 oder 1 und dann sollen die vor allen anderen dastehn.
aber irgendwie ignoriert mir der einfach alles :(

JackLemon 08.11.2004 03:39

musst hierarchisch sortieren. wenn die sticky-beiträge ganz oben sein sollen musst du _zuerst_ nach sticky sortieren, den rest (sowohl die sticky=1 als auch =0) sortierst du dann weiter... wenn du neue und geänderte beiträge "durcheinander" anzeigen möchtest wirst du das mit einem einzigen (gemeinsamen) feld machen müssen, sonst sortiert er immer zuerst nach dem einen, und die entstehenden untergruppen nach dem anderen. hoffe das war jetzt irgendwie verständlich...

Potassium 08.11.2004 07:16

naja das feld von der dem themen-datum soll ignoriert werden wenn schon antworten eingetragen wurden und dann stattdessen das datum der antwort zum sortieren benutzt werden. wie mach ich das?

snowman 08.11.2004 09:17

Ich habe mich mit Foren noch nicht wirklich beschäftigt, aber eventuell wäre ein Extra-Datumsfeld in der Thementabelle eine Möglichkeit, das auch mit dem Antwortdatum upgedatet wird, wenn Antworten erstellt werden.

gruss,
snowman

T.dot 08.11.2004 11:59

Ich hab zwar in meinem Forum noch keine Sticky-Posts (stehen ziemlich weit unten auf der TodoList ;) ), aber den ganzen kram von wegen letzer Beitrag, letzter User, etc.

tblForThreads sind die ForumThreads, tblForPosts sind die Posts,
FT_ID=Forumthread-id, FS_ID=Forumsection-id, Rest erklärt sich glaub ich von selbst.

Du müsstest afaik noch sticky auslesen und zusätzlich danach sortieren.

SQL-String schaut so aus:
SELECT tblForThreads.FT_ID, tblForThreads.FS_ID, tblForThreads.Hits,
Max(tblForPosts.Datum) AS MaxDatum, Count(FP_ID) As Answers,
Min(US_ID) as CreatorID, Max(US_ID) as LastposterID
FROM tblForThreads
INNER JOIN tblForPosts ON tblForThreads.FT_ID = tblForPosts.FT_ID
WHERE tblForThreads.FS_ID = $FSID
GROUP BY tblForThreads.FT_ID, tblForThreads.FS_ID, tblForThreads.Hits
ORDER BY MaxDatum DESC

mfg Thomas

Potassium 08.11.2004 17:24

hi danke erstmal.
@snowman: das prob ist ich möchte das ganze so "dynamisch" wie möglich halten. d.h. ich möchte keine endlose löschprozedur für posts sondern einfach den entsprechenden eintrag entfernen. und dann wäre die zeit ja wieder falsch.

@t.dot
ich hab nun in anlehnung an dein beispiel mit MAX() folgendes gemacht.
PHP-Code:

$query SQL("SELECT T.*,P.*,MAX(Post_Time) AS Max_Time FROM ".TABLE_TOPICS." T,".TABLE_POSTS." P WHERE P.Post_Topic_ID = T.Topic_ID AND T.Topic_Group = '".$Group_ID."' GROUP BY T.Topic_ID ORDER BY Max_Time DESC",__FILE__,__LINE__); 

aber wenn ein thema nun noch keine antworten enthällt soll das themen-datum genommen werden ansonsten aber nicht, wie bau ich das ein?

T.dot 08.11.2004 18:23

Nun ja, bei mir ist die Struktur so aufgebaut, dass ein Thread mindestens ein Post hat. Und sobald ein Post vorhanden ist gibts auch ein max(datum) davon.

Wenn du aber das Startpost/die Frage/... in die Threadtabelle schreibst (vermut ich mal, sonst müsst ja meines funktionieren) wird dir nichts anderes übrig bleiben als nachher per SQL abzufragen ob ein Wert für das max(datum) vorhanden ist.

Unter Umständen bekommst du auch ein Problem, da die Verknüpfung von Thread zu Post nicht mehr funktioniert, da ja keine Posts für den Thread vorhanden sind. Das kannst du aber über ein left oder right join, je nach anwendung, lösen...

mfg Thomas

Potassium 08.11.2004 18:45

Zitat:

Original geschrieben von T.dot
Wenn du aber das Startpost/die Frage/... in die Threadtabelle schreibst (vermut ich mal, sonst müsst ja meines funktionieren) wird dir nichts anderes übrig bleiben als nachher per SQL abzufragen ob ein Wert für das max(datum) vorhanden ist.

Unter Umständen bekommst du auch ein Problem, da die Verknüpfung von Thread zu Post nicht mehr funktioniert, da ja keine Posts für den Thread vorhanden sind. Das kannst du aber über ein left oder right join, je nach anwendung, lösen...

mfg Thomas

ad 1: wie frag ich das am besten ab?
ad2: wie meinst du mit joins? mit denen hab ich noch nie gearbeitet und ich hab ka was ich mit denen genau soll.

T.dot 08.11.2004 19:35

Sorry hab mich verschrieben, ich meinte eigentlich per PHP überprüfen ob der Wert vorhanden ist oder nicht.

Joins ganz einfach:

du machst es vermutlich so, wenn du was verknüpfst:
select * from tblThreads,tblPosts
where tblThreads.Thread_id=tblPosts.Thread_id

mit joins gelöst sieht das so aus

select * from tblThreads
INNER JOIN tblPosts ON tblThreads.Thread_id=tblPosts.Thread_id


jetzt gibt es die Möglichkeit die Tabellen so zu verknüpfen, das zb immer die Threadtabelle ausgelesen wird, auch wenn bei der Verknüpfung zur Poststabelle nix rauskommt.

select * from tblThreads
LEFT JOIN tblPosts ON tblThreads.Thread_id=tblPosts.Thread_id

right join ist das gleiche umgekehrt: es wird die tabelle rechts von join (in diesem fall tblPosts) genommen und immer die Posts ausgegeben, auch wenns keinen Thread dazu gibt (hat in diesem Fall keinen Sinn)

Dann gibts afaik noch outer join (hab ich nie verwendet) wenn ichs richtig im Kopf hab kriegst du dabei das Kreuzprodukt der beiden Tabellen, so wie wenn du "select * from tblThreads,tblPosts" machst.

Für genauere Details von Joins hab ich mich nie interessiert, aber Google und co wissen sicher mehr ;)

Nachdem du wahrscheinlich eh irgendwas wie phpmyadmin oder so hast kannst du ja leicht die verschiedenen ergebnisse der sql-abfragen überprüfen...

mfg Thomas

Potassium 08.11.2004 19:53

OMG das is schwer. nun hab ich folgendes uamgebastelt:
PHP-Code:

$query SQL("SELECT T.*,P.*,MAX(Post_Time) AS Max_Post_Time FROM ".TABLE_TOPICS." T LEFT JOIN ".TABLE_POSTS." P ON T.Topic_ID = P.Post_Topic_ID WHERE T.Topic_Group = '".$Group_ID."' GROUP BY Topic_ID ORDER BY Max_Post_Time DESC",__FILE__,__LINE__); 

nun hat Max_Post_Time den wert NULL wenn das posting ned vorhanden is ich will aber wenn das posting ned vorhanden is, das Max_post_Time den wert Topic_Date hat. *hrmpf*
geht das auch und wenn ja wie?

T.dot 08.11.2004 20:34

Denke nicht, dass das geht. Zumindest wüsste ich nicht wie, da ich ned glaub das sql irgendwelche if syntax-dinger für ausgelesen werte unterstützt. Sowas mach ich dann meistens per PHP, also Werte auslesen und nachschauen ob vorhanden/nicht und dann halt irgendwas anderes machen...

Du könntest aber auf die Lösung umsteigen, dass du einfach bereits das erste Post in die Posttabelle reinspeicherst, wüsste eigentlich nicht, was dagegen sprechen würd. Außer du hast leere Themen in deinem Forum?

Einziges Problem das auftritt ist das Auslesen des Threattitels, falls dieses dem Titel des ersten Posts entsprechen soll...

ich würde (auch wenn jetz ne redundanz dabei is) das ganze so aufbauen:

Threads:
- Thread_ID -> eindeutige nummer fürn thread
- (Section_ID -> zu welcher Section gehört dieser Thread, je nachdem ob du damit arbeitest)
- Thread_Titel -> um das greade erwähnte Problem zu übergehen: Threadtitel wird im ersten Post und in Threadtabelle gespeichert
- Hits -> Anzahl der Zugriffe

Posts:
- Post_ID -> eindeutige PostNummer
- Thread_ID -> zu welchen Thread gehört das Post
- User_ID -> wer hats geschrieben
- Datum -> wann geschrieben
- Titel -> Posttitel (falls jedes Post einen Titel haben darf, ala wcm forum)
- Beitrag -> der Text zum Post

hab jetz mal nur die wichtigsten Felder genommen, lässt sich wohl ewig weiterführen...

mfg Thomas

snowman 09.11.2004 09:02

Zitat:

Original geschrieben von Potassium
hi danke erstmal.
@snowman: das prob ist ich möchte das ganze so "dynamisch" wie möglich halten. d.h. ich möchte keine endlose löschprozedur für posts sondern einfach den entsprechenden eintrag entfernen. und dann wäre die zeit ja wieder falsch.

verstehe das beschriebene problem nicht, weil löschen wirst du ja hoffentlich über eine individuelle id.

gruss,
snowman

T.dot 09.11.2004 11:44

ich glaubs zu verstehen:

angenommen du aktualisierst immer das datum wenn ein neues post hinzugefügt wird, dann musst du auch wenn du ein post löscht das datum aktualisieren, falls das post das letzte neue post ist.

das bedeutet wieder diverse abfragen in php und update in sql, etc.

ich denke das potassium das vermeiden will und möglichst alles über einfach sql-statements lösen möchte.

mfg Thomas :)

Potassium 09.11.2004 13:11

Zitat:

Original geschrieben von T.dot
ich glaubs zu verstehen:

angenommen du aktualisierst immer das datum wenn ein neues post hinzugefügt wird, dann musst du auch wenn du ein post löscht das datum aktualisieren, falls das post das letzte neue post ist.

das bedeutet wieder diverse abfragen in php und update in sql, etc.

ich denke das potassium das vermeiden will und möglichst alles über einfach sql-statements lösen möchte.

mfg Thomas :)

:ja::ja::ja::ja::ja:
ganz genau :)

Potassium 09.11.2004 23:05

*push*
hat keiner eine idee?
es ist wirklich wichtig.

T.dot 10.11.2004 22:08

los googlos helpos immros (google hilft immer auf neuspanisch)

zieh dir mal das rein:
http://dev.mysql.com/doc/mysql/en/Co...functions.html

wennst da sowas wie

IFNULL(Max(PostDatum),ThreadDatum) machst könnts fast funktionieren - aber garantieren kann ich nix...

:D

mfg Thomas

Potassium 10.11.2004 22:57

Code:

ORDER BY (IF(P.Post_Time IS NULL,Topic_Date,Post_Time)) DESC
und er sortiet trotzdem immer nach Topic_Date :heul:
das gibts doch nicht, dass sowas nie jemand braucht.

T.dot 11.11.2004 20:18

wie schaffst du das?

probiers mal mit dem:

SELECT tblThread.*,max(tblPost.PostDatum),
ifnull(max(tblPost.PostDatum),tblThread.ThreadDatu m) as DeppadesFeld
FROM tblThread
LEFT JOIN tblPost
ON tblThread.TH_ID=tblPost.TH_ID
GROUP BY tblThread.TH_ID
ORDER BY DeppadesFeld DESC


das funktioniert bei mir wonderbra... :confused:

Potassium 11.11.2004 20:52

boah du bist genial :eek:
VIIIIIIIIIIIEEEEEEEEEELLLLLEN DANK :bier:
hast was gut bei mir :)

kommst aufs forumstreffen?

T.dot 11.11.2004 20:57

ne, bin anderweitig behindert :D


Alle Zeitangaben in WEZ +2. Es ist jetzt 14:48 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
© 2009 FSL Verlag