2012-03-19 2 views
1

Я пишу модуль плагина для системы, использующей CakePHP 1.2, и я новичок в структуре. Как сделать следующий запрос: Cake?INNER JOIN with GROUP By the CakePHP way

SELECT a.id, a.name, COUNT(a.id) AS comments 
FROM articles a LEFT JOIN comments c ON a.id = c.item_id 
GROUP BY a.id 
ORDER BY comments DESC; 

Я не могу редактировать статьи или комментарий модели, но я стараюсь это в модели моего плагина и это не дает тот же результат:

$this->loadModel('Article'); 
$options['fields'] = array('Article.id', 'Article.name', 
       'COUNT(Article.id) AS comments'); 
$options['joins'] = array(
    array('table' => 'comments', 
      'alias' => 'c', 
      'type' => 'INNER', 
      'conditions' => array(
      'Article.id = c.item_id') 
     )); 
$options['group'] = array('Article.id'); 
$options['order'] = 'comments DESC'; 
$options['limit'] = 5; 
$rows = $this->Article->find('all', $options); 

Кроме того, я не уверен, но я думаю, что класс статьи, возможно, уже есть:

public $actsAs = array('Containable'); 
public $hasMany = array('Comment'); 
+0

В вашем обычном sql у вас есть «LEFT JOIN», в Торт вы определяете 'type => INNER'. Это намеренно? – biziclop

+0

Я верю, что INNER вернее, и вы используете LEFT и RIGHT только с соединениями OUTER, но по моему опыту MySQL рассматривает JOIN, LEFT JOIN и INNER JOIN все одинаковые –

+0

Нет, 'INNER' и' LEFT' ('LEFT OUTER') объединяются обрабатываются по-разному. Однако mysql будет использовать 'LEFT JOIN' как' INNER JOIN', если вы добавите дополнительные условия в объединенную таблицу к предложению 'WHERE'. – bfavaretto

ответ

1

Очень неожиданный ответ:

Версия CakePHP используется этот проект (о котором я ничего не могу поделать) представляет собой бета-версию версии 1.2.0.6311, выпущенную в 2008-01-02, и согласно this article группа по функциональности в методе поиска модели Cake была добавлена ​​только в мае 2008 года

+0

Ha! Я никогда не узнаю этого! Таким образом, вам нужно будет обновить Cake или забыть о «методе торта» и просто запустить запрос с помощью «Model :: query». – bfavaretto

+0

Да, я дезинфицирую свои параметры и использую $ this-> query (...) –

3

Я думаю, вы также должны добавить foreignKey => FALSE к вашему присоединиться к определению:

$options['joins'] = array(
    array('table' => 'comments', 
      'alias' => 'c', 
      'type' => 'INNER', 
      'foreignKey' => FALSE, 
      'conditions' => array('Article.id = c.item_id') 
    ) 
); 

Кроме того, если вы сами форсируете соединения, вы должны избавиться от любых предыдущих ассоциаций стиля Cake, либо передав recursive => FALSE в качестве опций, либо применив unbindModel к каждой связанной модели.

UPDATE

Основываясь на том, что вы сказали в комментариях, вот что я думаю, что вам нужно:

$options['fields'] = array(
    'Article.id', 
    'Article.name', 
    'COUNT(DISTINCT c.id) AS comments' 
); 
$options['joins'] = array(
    array(
     'table' => 'comments', 
     'alias' => 'c', 
     'type' => 'LEFT OUTER', 
     'foreignKey' => FALSE, 
     'conditions' => array('Article.id = c.item_id') 
    ) 
); 
$options['group'] = array('Article.id'); 
$options['order'] = 'COUNT(DISTINCT c.id) DESC'; 
$rows = $this->Article->find('all', $options); 
+0

Извините, что я пробовал все три предложения без везения. Возвращается только одна строка, и у нее неправильный счетчик комментариев. –

+0

@JannieT, см. Мой обновленный ответ. – bfavaretto

+0

Извините, не кубики. –