2012-04-25 10 views
2

私は前の質問を削除して理解しやすくしています。唯一の最後のスレッド応答を取得するにはどこ私はIDUSER、「私は答えた最後のユーザーだ」でない場合(、日付順、クエリを作成する必要がMySQLの難しいクエリ

ID:INT->PRIMARY-KEY->AUTO_INCREMENT 
IDTOPIC:INT (0 if it is the "father" topic OR father's ID if it's a reply) 
IDUSER:INT (ID of user who posted) 
CONTENT:MEDIUMTEXT 
DATE:TIMESTAMP 

: 私はこのデータベーススキーマとのフォーラムを開発しています<> $ userid)または返事がない場合は父のスレッドのトピック。 でも話題や結果を返信、私は最初のスレッドIDTOPIC/IDUSERを印刷する必要が

私の理想的な結果は次のようにする必要があります:

ID:IDTOPIC:IDUSER:CONTENT:DATE:IDLASTREPLY:IDLASTUSERREPLY:LASTCONTENTREPLY:LASTDATEREPLY 

最後の4つのフィールドがNULLであれば問題はありません。 私はできるだけ速い質問が必要です。 私を助けてください!

+0

:私は

通知表FIELDS(ONLYの$ USERIDによって行われていない返信のを示すために)通知クエリとしてそれを使用したいので、新しいnoticationsテーブルがあり、あなたのデータのための最良の構造ではないかもしれない "隣接リスト"を使って投稿します。おそらく、データベースに階層データを格納する別の方法を研究する必要があります。 [この質問](http://stackoverflow.com/questions/192220/what-is-the-most-efficient-elegant-way-to-parsea-a-flat-table-into-a-tree)は良いです開始。 – eggyal

+0

しかし、フォーラムを作る私の方法は、joomla/phpBBのような他の "有名な"製品とまったく同じです...彼らはすべてIDTOPICまたはPARENTというフィールドを持つ単一のテーブルを使って返信からトピックを分割しています... –

答えて

1
SELECT fa.ID, fa.IDTOPIC, fa.IDUSER, fa.CONTENT, fa.DATE, 
    re.ID as IDLASTREPLY, 
    re.IDUSER as IDLASTUSERREPLY, 
    re.CONTENT as LASTCONTENTREPLY, 
    re.DATE as LASTDATEREPLY, 
    CASE WHEN (re.DATE is NULL) THEN fa.DATE ELSE re.DATE END as LASTUPDATE 
FROM post fa 
    LEFT JOIN post re ON re.ID = 
    (SELECT ID FROM post WHERE IDTOPIC = fa.ID ORDER BY DATE DESC LIMIT 1) 
WHERE fa.IDTOPIC = 0 
ORDER BY LASTUPDATE DESC 

とORDERを好きなように指定します。
しかし、それはあまり良いパフォーマンスではありません。私はあなたのテーブル構造を改善できると思います。

編集:私は私のことでスレッドをフィルタリングしていたときに残念なことに、この選択は、テーブルの上に約900レコードの合計で、...いくつかの記事の後に 今日はあまり良くないですORDER

+0

ありがとうしかし、返信がない場合、re.DATEはnullであり、それが表示される最初のレコードになるため、このように私はORDERできませんでした。 –

+1

OK、自分のコードを編集し、LASTUPDATE列を追加します。どうですか? – tosin

+0

いいえ、正しい順序は次のとおりです。CASE WHEN(re.DATEはNULLです)その後fa.DATE ELSE re.DATE ENDとしてLASTUPDATE –

0

ためLASTUPDATEを追加ユーザーID(45個の異なるスレッド!)、MySQLは0.30秒必要です(開始時には0.04/0.05秒しか必要ありませんでした...劣化は私が購読したスレッドの数に比例します) これは、サブスクリプションされた300の別個のスレッドがあります。私はこのクエリのために約2秒待つべきです...それはあまりにも多いです。 奇妙なことは、私がこのクエリーを "制限して0,10"にするか、完全なクエリーを得ると、実行速度が変わらないということです!これは私がそれが良いとは思えない理由です...私はそれが私が制限しても、全体のデータを選択しなければならないと思います。 解決する方法はありません。これはセットアップの質問です。 ID、idcontentユーザーID、あなたが保存している

SELECT 
    CASE WHEN (re.id is NULL) THEN fa.id ELSE re.id END AS id, 
    fa.id as idtopic, 
    CASE WHEN (re.userid is NULL) THEN fa.userid ELSE re.userid END AS userid, 
    CASE WHEN (re.content is NULL) THEN fa.content ELSE re.content END AS content, 
    n.notify, 
    u.id as reuserid, u.name, u.surname, u.photo, 
    CASE WHEN (re.date is NULL) THEN unix_timestamp(fa.date) ELSE unix_timestamp(re.date) END AS LASTUPDATE 
FROM notifications AS n 
LEFT JOIN post AS fa 
    ON fa.id = n.idcontent 
LEFT JOIN post AS re 
    ON re.id=(SELECT ID FROM post WHERE IDTOPIC = fa.ID AND userid <> $USERID ORDER BY DATE DESC LIMIT 1) 
LEFT JOIN users AS u 
    ON u.id = (CASE WHEN (re.userid is NULL) THEN fa.userid ELSE re.userid END) 
WHERE 
    n.userid = $USERID 
    AND NOT (fa.userid = $USERID AND re.userid = $USERID)