php - querybuilder - Query Builder y Group By en dos columnas en Symfony2/Doctrine generan duplicados
query builder symfony (2)
Estoy creando un paquete de mensajes donde los mensajes se agrupan por contactos. En mi página de índice, muestro diferentes hilos. Cuando hace clic en un hilo, muestra todos los mensajes intercambiados entre usted y su contacto. Utilizo un Generador de consultas para mostrar los subprocesos en mi página de índice:
$qb = $this->createQueryBuilder(''m'')
->where(''m.from = ?1 or m.to = ?1'')
->groupBy(''m.to, m.from'')
->orderBy(''m.date'', ''DESC'')
->setParameter(1, $user->getId())
->setMaxResults($pagination) // limit
->setFirstResult($pagination * $page) // offset
;
Si tengo 3 entradas, por ejemplo:
+----+------+----+
| id | from | to |
+----+------+----+
| 1 | 1 | 2 |
+----+------+----+
| 2 | 2 | 1 |
+----+------+----+
| 3 | 1 | 2 |
+----+------+----+
Espero:
+----+------+----+
| id | from | to |
+----+------+----+
| 3 | 1 | 2 |
+----+------+----+
Pero me sale:
+----+------+----+
| id | from | to |
+----+------+----+
| 2 | 2 | 1 |
+----+------+----+
| 3 | 1 | 2 |
+----+------+----+
Encontré una forma de hacerlo con SQL, usando el mismo alias para from_id y to_id:
SELECT id, from_id as c, to_id as c FROM Message WHERE c = 1 GROUP BY from_id, to_id
Pero no sé cómo hacerlo con Doctrine.
EDITAR:
Hasta que tenga una mejor idea, uso una tecla para "agrupar por" fácilmente.
// entity
/**
* @ORM/Column(name="key", type="string", length=40)
*/
private $key;
/**
* @ORM/PrePersist()
*/
public function setOnPrePersist()
{
if($this->from < $this->to) {
$key = $this->from . ''t'' . $this->to;
} else {
$key = $this->to . ''t'' . $this->from;
}
$this->key = $key;
}
// query builder
$qb = $this->createQueryBuilder(''m'')
->where(''m.from = ?1 or m.to = ?1'')
->groupBy(''m.key'')
->orderBy(''m.date'', ''DESC'')
->setParameter(1, $user->getId())
->setMaxResults($pagination) // limit
->setFirstResult($pagination * $page) // offset
;
return $qb->getQuery()->getResult();
Intente lo siguiente usando el método DQL de doctrina:
$query = $em->createQuery("SELECT m.id, m.from_id as c, m.to_id as c FROM AcmeDemoBunlde:Message as m WHERE m.c = 1 GROUP BY m.from_id, m.to_id");
$messageDetails = $query->getResult();
En lugar de AcmeDemoBundle, sustitúyalo por el nombre del paquete correspondiente.
en caso de que tenga muchas columnas en ''agrupar por'', debe usar el método addGroupBy ().
$qb = $this->createQueryBuilder(''m'')
->where(''m.from = ?1 or m.to = ?1'')
->groupBy(''m.to'')
->addGroupBy(''m.from'')
->orderBy(''m.date'', ''DESC'')
->setParameter(1, $user->getId())
->setMaxResults($pagination) // limit
->setFirstResult($pagination * $page) // offset
;
:)