Ver Mensaje Individual
  #1 (permalink)  
Antiguo 20/07/2015, 05:36
Avatar de Uncontroled_Duck
Uncontroled_Duck
Colaborador
 
Fecha de Ingreso: mayo-2011
Ubicación: Málaga [Spain]
Mensajes: 806
Antigüedad: 13 años
Puntos: 261
Planteamiento de consulta en Doctrine

Buenas, lo he puesto aquí por que, aunque tiene que ver directamente con las consultas a la base de datos, es un derivado de MySql para PHP.

El tema es el siguiente, tengo dos entidades de Doctrine relacionadas entre si, una que es Profile y otra que es Specialty.

- Profile tiene una relación Many To Many con Specialty.
- Specialty tiene una relación One To Many con si misma (Self-Referencing). (Dejo abajo los Entities)

Con esta estructura, las Specialties se guardan así:
Código:
id	parent_id	specialty
--	--		--
1	null		Specialty Parent
2	1		Specialty Children
3	1		Specialty Children
4	null		Specialty Parent
5	4		Specialty Children
6	4		Specialty Children
7	4		Specialty Children
8	4		Specialty Children
//....
Y los Profiles se guardan así:
Código:
profile_id	specialty_id
--		--
1		1
1		2
2		1
2		2
2		3
//....
El planteamiento es seleccionar solo las Especialidades padre y contar todos los perfiles asociados, incluyendo también todos los perfiles de las especialidades hijas.

Con esta consulta consigo obtener todos los registros.
Código PHP:
$dql '';
$dql .= 'SELECT s1, pro1, COUNT(pro1.id) as numProfiles  ';
$dql .= 'FROM \Resources\Entity\Specialty s1 ';
$dql .= 'LEFT JOIN s1.parent p1 ';
$dql .= 'LEFT JOIN s1.profiles pro1 ';
$dql .= 'GROUP BY s1.id, pro1.id'
Pero el resultado me cuenta solo 1 perfil a pesar de tener mas Perfiles asociados.

Código:
array (size=811)
  0 => 
    array (size=2)
      0 => 
        array (size=10)
          'id' => int 1
          'title' => string 'Title' (length=5)
          'value' => string 'value' (length=5)
          'profiles' => 
            array (size=1)
              0 => 
                array (size=27)
                  'id' => int 1
                  'firstName' => string 'name' (length=5)
              1 => 
                array (size=27)
                  'id' => int 1
                  'firstName' => string 'name' (length=5)
      'numProfiles' => string '1' (length=1)
  1 => 
    array (size=2)
      0 => 
        array (size=10)
          'id' => int 1
          'title' => string 'Title' (length=5)
          'value' => string 'value' (length=5)
          'profiles' => 
            array (size=1)
              0 => 
                array (size=27)
                  'id' => int 1
                  'firstName' => string 'name' (length=5)
              1 => 
                array (size=27)
                  'id' => int 1
                  'firstName' => string 'name' (length=5)
      'numProfiles' => string '1' (length=1)
Y si condiciono la selección para que tome solo las Especialidades Padre
Código PHP:
$dql '';
$dql .= 'SELECT s1, pro1, COUNT(pro1.id) as numProfiles  ';
$dql .= 'FROM \Resources\Entity\Specialty s1 ';
$dql .= 'LEFT JOIN s1.parent p1 ';
$dql .= 'LEFT JOIN s1.profiles pro1 ';
$dql .= 'WHERE s1.parent IS NULL ';
$dql .= 'GROUP BY s1.id, pro1.id'
Me toma solo las categorías Padre correctamente, pero solo los Perfiles Asociados a estas.

En fin, que llevo todo el fin de semana haciendo pruebas y no he conseguido aplicar la lógica correctamente para sacarlo.

Imagino que a alguien se le habrá presentado una situación similar, o algo de orientación se agradecería.

Gracias de antemano y saludos a todos.

PD.: Dejo por aquí las Entidades.

Los Entities
Código PHP:
/**
 * @ORM\Entity
 * @ORM\Table(name="profiles")
 */
class Profile
{
    
/**
     * @ORM\ManyToMany(targetEntity="Specialty", inversedBy="profiles")
     * @ORM\JoinTable(name="mtm_profile_specialty")
     */
    
private $specialties;

Código PHP:
/**
 * @ORM\Entity
 * @ORM\Table(name="specialties")
 */
class Specialty
{
    
/**
     * @ORM\OneToMany(targetEntity="Specialty", mappedBy="parent")
     */
    
private $children;

    
/**
     * @ORM\ManyToOne(targetEntity="Specialty", inversedBy="children")
     * @ORM\JoinColumn(name="parent_id", referencedColumnName="id")
     */
    
private $parent;

    
/**
     * @ORM\ManyToMany(targetEntity="Profile", mappedBy="specialties")
     */
    
private $profiles;

__________________
Todos agradeceremos que pongas el código en su respectivo Highlight