2012-09-28 29 views
5

Estoy tratando de crear una consulta para recuperar objetos de una base de datos de Doctrine, ordenados por el número de miembros de una relación específica de uno a varios.¿Cómo ordenar una consulta Doctrine DQL por el número o los miembros de una relación?

Más específicamente: Tengo dos entidades: Persona y Federación. Una persona puede ser miembro de una federación (la persona tiene una relación de 'federación') y una federación puede tener n personas (Federación como 'relación de personas').

Me gustaría crear una consulta DQL que devuelva la lista de Federaciones, ordenada por cuántas personas son miembros de esa Federación. Algo en esta línea:

SELECT f FROM AcmeStatsBundle:Federation f ORDER BY [number of members of f.people] 

Ese sería el primer paso. Hay un segundo paso adicional, que no sé si es posible lograr con una sola consulta, que sería filtrar los miembros de la relación antes del recuento. De este modo:

SELECT f FROM AcmeStatsBundle:Federation f ORDER BY [number of (f.people p where p.attr = value)] 

Ese segundo sería el resultado óptimo, pero el primero de ellos satisface mis necesidades, si el segundo caso no es factible en una sola consulta.

Gracias de antemano.

Respuesta

4

Hay 5 funciones agregadas en DQL se pueden utilizar (Doctrina 2.2): AVG, COUNT, MIN, MAX y SUM.

La siguiente consulta debería funcionar:

SELECT f 
FROM AcmeStatsBundle:Federation f 
LEFT JOIN f.people p 
GROUP BY f.id 
ORDER BY COUNT(p) 
WHERE p.attr = :some_value 

Para más trucos DQL le sugiero que busque hasta official Doctrine docs.

+2

Gracias por la respuesta! Tuve que hacer ligeras modificaciones a la consulta, ya que creo que no se puede ORDENAR por un agregado sin SELECCIONARLO. Así que la consulta final es la siguiente: 'SELECCIONE f, COUNT (p) como qtd DE AcmeStatsBundle: Federación f UNIÓN IZQUIERDA f.personas p DONDE p.attr =: some_value GROUP BY f.id ORDEN POR qtr' : D –

6

Usted podría hacer algo en la línea de:

public function getFederationsOrderedByNumberOfPeople() 
{ 
    return $this->createQueryBuilder('f') 
     ->addSelect('COUNT(p) AS HIDDEN personCount'); 
     ->leftJoin('f.people', 'p'); 
     ->groupBy('f') 
     ->orderBy('personCount', 'DESC'); 
} 

Se añadió la palabra escondida en Doctrina 2.2, significa que el campo seleccionado no estará en los resultados, y en este caso significa que usted solo recupera tus entidades en lugar de una matriz.

referencia a la documentación DQL SELECT: http://doctrine-orm.readthedocs.org/en/latest/reference/dql-doctrine-query-language.html#dql-select-examples

+0

¡Gracias! ¡Esta es la manera de hacerlo! – Russ

Cuestiones relacionadas