construir um complexo de consulta SQL (ou consultas)
Pergunta
Como parte de um grande web-app (usando o CakePHP), estou montando um blog simples do sistema.As relações são extremamente simples:cada Usuário tem um Blog, que tem muitas Entradas, que tem muitos Comentários.
Um elemento que eu gostaria de incorporar é uma lista de "Popular Entradas". Popular Entradas foram definidos como aqueles com o maior número de Comentários no último mês, e, finalmente, eles precisam ser solicitados pelo número de Comentários recentes.
Idealmente, eu gostaria que a solução para ficar dentro de Bolo do Modelo de dados-recuperação de aparelhos (Model->find()
, etc.), mas eu não sou otimistas sobre isso.
Alguém tem um inteligente sistema/solução elegante?Eu estou preparando-me para alguns selvagens SQL hacking para fazer este trabalho...
Solução
Heh, eu estava prestes a voltar com essencialmente a mesma resposta (usando o Bolo do Modelo::encontrar):
$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' )
)
)
));
Ele não é perfeito, mas funciona e pode ser melhorado.
Eu fiz uma melhora adicional, usando o Containable comportamento para extrair os dados de Entrada, em vez de o Comentário de dados.
Outras dicas
Não deve ser muito ruim, você só precisa de um grupo (isto é, fora o tipo da minha cabeça, então perdoe os erros de sintaxe):
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
Se você não fosse fussed sobre o horário de natureza sensível dos comentários, você poderia fazer uso do CakePHP counterCache funcionalidade adicionando um "comment_count" campo para as entradas de tabela, configurando o counterCache chave do Comentário belongsTo Entrada de associação com este campo e, em seguida, chamar o método find() no modelo de Entrada.
Você provavelmente quer um ONDE cláusula obter últimos 30 dias comentários:
SELECT entry-id, count(id) AS c
FROM comment
WHERE comment_date + 30 >= sysdate
GROUP BY entry-id
ORDER BY c DESC