0

Codeigniter; アクティブレコードクラス

そのトピックから、CodeIgniterについて質問しました。代わりに、完全に生で実行することを考えました。

これは私の現在のクエリです。

 SELECT `forums`.*, 
        Count(topics.id) threads, 
        Count(replies.id) replies, 
        `users`.`url` user_url, 
        `users`.`name` user_name,
        `ranks`.`name` user_rank  
 FROM (`forums`)  
 LEFT JOIN `topics` ON `topics`.`f_id` = `forums`.`id`  
 LEFT JOIN `replies` ON `replies`.`t_id` = `topics`.`id`  
 LEFT JOIN `users` ON `users`.`id` = `topics`.`a_id`  
 LEFT JOIN `ranks` ON `users`.`status` = `ranks`.`id`  
 LEFT JOIN (  
 SELECT `topics`.`url` topic_url, `topics`.`name` topic_name  
 FROM `topics`  
 ORDER BY `created` DESC  
 LIMIT 1  
 ) last_post ON `topics`.`f_id` = `forums`.`id`  
 GROUP BY `forums`.`id`

だから私がやろうとしているのは、すべてを1つの気の利いた行にまとめることです。「LastPostBy」以外はすべて機能しています。後でLEFT JOIN追加したものを削除すると、最後の投稿ではなく最初の投稿が表示されます。

だから私の質問は; 私は今何を間違っているのですか?

また、おまけの質問ですが、PHPとMySQLに関しては、私よりも少し知識が豊富な友人と話をしました。彼は、すべてをデータベース、last_post、スレッド数に保存するように指示しました。返信します。

前もって感謝します。

アップデート

これがフォーラムの表です

CREATE TABLE IF NOT EXISTS `forums` (  
  `id`    int(11) NOT NULL AUTO_INCREMENT,  
  `c_id`  int(11) NOT NULL,  
  `url`   varchar(255) NOT NULL,  
  `name`  varchar(255) NOT NULL,  
  `desc`  text NOT NULL,  
PRIMARY KEY (`id`),  
KEY `url` (`url`,`name`)  
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=9 ;  

これがトピックテーブルです

CREATE TABLE IF NOT EXISTS `topics` (  
  `id` int(11) NOT NULL AUTO_INCREMENT,  
  `f_id`    int(11) NOT NULL,  
  `url`     varchar(255) NOT NULL,  
  `name`    varchar(255) NOT NULL,  
  `desc`    varchar(255) NOT NULL,  
  `body`    text NOT NULL,  
  `a_id`    int(11) NOT NULL,  
  `created` int(11) NOT NULL,  
  `edited`  int(11) NOT NULL,  
PRIMARY KEY (`id`),  
KEY `head` (`name`)  
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=10 ;

また、最初に行ったように、マークダウン編集で表示方法を更新しようとしました。これがより魅力的であることを願っています。

4

1 に答える 1

2

これが解決策です。これが最も効率的な解決策ではないと思いますが、機能するはずです。TopicsSELECTを最初のSELECT行に移動したことに注意してください。

SELECT `forums`.*, 
        Count(topics.id) threads, 
        Count(replies.id) replies, 
        `users`.`url` user_url, 
        `users`.`name` user_name,
        `ranks`.`name` user_rank,
        (SELECT `topics`.`url` 
         FROM `topics` 
         WHERE `topics`.`f_id` = `forums`.`id` 
         ORDER BY `created` DESC LIMIT 1) topic_url,
        (SELECT  `topics`.`name`
         FROM `topics` 
         WHERE `topics`.`f_id` = `forums`.`id` 
         ORDER BY `created` DESC LIMIT 1) topic_name 
 FROM (`forums`) 
 LEFT JOIN `topics` ON `topics`.`f_id` = `forums`.`id`   
 LEFT JOIN `replies` ON `replies`.`t_id` = `topics`.`id`  
 LEFT JOIN `users` ON `users`.`id` = `topics`.`a_id`  
 LEFT JOIN `ranks` ON `users`.`status` = `ranks`.`id`  
 GROUP BY `forums`.`id`

可能なより効率的な方法

これが高速かどうかをテストするためのデータはありませんが、これは別の方法です(MySQLのROW_NUMBER()に基づいています)。これには1つの文字列が添付されており、topicsテーブルに含めることはできません。重複f_idcreated組み合わせ:

SELECT `forums`.*, 
        Count(topics.id) threads, 
        Count(replies.id) replies, 
        `users`.`url` user_url, 
        `users`.`name` user_name,
        `ranks`.`name` user_rank,
        t.url topic_url,
        t.name topic_name
 FROM (`forums`)  
 LEFT JOIN (SELECT t0.id, t0.f_id, t0.url, t0.name, t0.a_id
            FROM topics AS t0
            LEFT JOIN topics AS t1 ON t0.f_id=t1.f_id AND t1.created>t0.created
            WHERE t1.id IS NULL) AS t
            ON t.f_id = forums.id
 LEFT JOIN `replies` ON `replies`.`t_id` = t.`id`  
 LEFT JOIN `users` ON `users`.`id` = t.`a_id`  
 LEFT JOIN `ranks` ON `users`.`status` = `ranks`.`id` 
 GROUP BY `forums`.`id`

最初にそれが機能するかどうかを確認し、次にそれがより高速であるかどうかを確認するために、それを試してみてください。ご返信をお待ちしております。

于 2012-07-24T22:03:59.550 に答える