2008-09-09 10 views
1

Als Teil einer größeren Web-App (mit CakePHP), stelle ich ein einfaches Blog-System zusammen. Die Beziehungen sind äußerst einfach: Jeder Benutzer hat einen Blog, der viele Einträge hat, die viele Kommentare enthalten.eine komplexe SQL-Abfrage (oder Abfragen) erstellen

Ein Element, das ich gerne einfügen würde, ist eine Liste von "Beliebte Einträge". Beliebte Einträge wurden als diejenigen mit den meisten Kommentaren im letzten Monat definiert und müssen letztendlich nach der Anzahl der letzten Kommentare sortiert werden.

Idealerweise hätte ich gerne, dass die Lösung im Datenwiedergewinnungsgerät von Cake's Model (Model->find(), usw.) bleibt, aber ich bin nicht optimistisch.

Wer hat eine clevere/elegante Lösung? Ich bereite mich auf einige wilde SQL-Hacking, um diese Arbeit zu machen ...

Antwort

4

Heh, ich war gerade dabei, mit im wesentlichen die gleiche Antwort zu kommen (Cake Modell mit :: finden):

$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') 
     ) 
    ) 
)); 

Es ist nicht perfekt, aber es funktioniert und kann verbessert werden.

Ich machte eine zusätzliche Verbesserung, die das Containable-Verhalten verwendet, um die Eintragsdaten anstelle der Kommentardaten zu extrahieren.

2

Sollte nicht so schlimm sein, brauchen Sie nur eine Gruppe von (das ist von der Art meines Kopfes, so vergeben Syntaxfehler):

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 
0

Sie wollen wahrscheinlich eine WHERE Klausel nur letzten 30 Tagen Kommentare zu erhalten:

SELECT entry-id, count(id) AS c 
FROM comment 
WHERE comment_date + 30 >= sysdate 
GROUP BY entry-id 
ORDER BY c DESC 
1

Wenn Sie nicht über die zeitkritische Art der Kommentare besorgt waren, könnten Sie die counterCache-Funktionalität von CakePHP nutzen, indem Sie ein Feld "comment_count" zur Tabelle entries hinzufügen, indem Sie den counterCache-Schlüssel der Commit-Liste mit dem Eintrag goesTo Entry konfigurieren In diesem Feld rufen Sie find() im Entry-Modell auf.

Verwandte Themen