質問
より大きな Web アプリ (CakePHP を使用) の一部として、シンプルなブログ システムを構築しています。関係は非常に単純です。各ユーザーはブログを持っており、そこには多くのエントリと多くのコメントがあります。
私が組み込みたい要素は、「人気エントリ」のリストです。人気のあるエントリは、先月のコメントが最も多いものとして定義されており、最終的には最近のコメントの数で注文する必要があります。
理想的には、ソリューションを Cake の Model データ検索装置内に留めておきたいと思います (Model->find()
, 、など)、しかし私はこれについて楽観的ではありません。
賢い/エレガントな解決策を持っている人はいますか?これを機能させるために、ワイルドな SQL ハッキングに挑戦しています...
解決
へえ、私はちょうど本質的に同じ答えが返ってくるところでした(Cake の Model::find を使用):
$this->loadModel('Comment');
$this->Comment->find( 'all', array(
'fields' => array('COUNT(Comment.id) AS popularCount'),
'conditions' => array(
'Comment.created >' => strtotime('-1 month')
),
'group' => 'Comment.blog_post_id',
'order' => 'popularCount DESC',
'contain' => array(
'Entry' => array(
'fields' => array( 'Entry.title' )
)
)
));
完璧ではありませんが、機能しており、改善することができます。
Containable の動作を使用して、コメント データの代わりにエントリ データを抽出するという追加の改善を行いました。
他のヒント
それほど悪くはありません。グループ化が必要なだけです (これは私の頭のタイプから外れているので、構文エラーはご容赦ください)。
SELECT entry-id, count(id) AS c
FROM comment
WHERE comment.createdate >= DATE_SUB(CURDATE(), INTERVAL 1 MONTH)
GROUP BY entry-id
ORDER BY c DESC
コメントの時間に敏感な性質について気にしない場合は、エントリ テーブルに「comment_count」フィールドを追加し、このフィールドと Comment のbelongsTo Entry 関連付けの counterCache キーを設定することで、CakePHP の counterCache 機能を利用できます。エントリーモデルで find() を呼び出します。
あなたはおそらく、 どこ 過去 30 日間のコメントだけを取得する句:
SELECT entry-id, count(id) AS c
FROM comment
WHERE comment_date + 30 >= sysdate
GROUP BY entry-id
ORDER BY c DESC