utiliza unir tablas que para interna horizontalmente ejemplos consultas consulta concatenar sql symfony doctrine2

sql - unir - Constructor de consultas de Doctrine que usa unión interna con condiciones



union mysql dos tablas (2)

Me gustaría construir el siguiente SQL usando el generador de consultas de Doctrine:

select c.* from customer c join phone p on p.customer_id = c.id and p.phone = :phone where c.username = :username

Primero lo intenté

$qb->select(''c'') ->innerJoin(''c.phones'', ''p'', Join::ON, $qb->expr()->andx( $qb->expr()->eq(''p.customerId'', ''c.id''), $qb->expr()->eq(''p.phone'', '':phone'') )) ->where(''c.username = :username'');

Pero recibo el siguiente error

Error: expected end of string, got ''ON''

Entonces probé

$qb->select(''c'') ->innerJoin(''c.phones'', ''p'') ->where(''c.username = :username'') ->andWhere(''p.phone = :phone'');

que parece estar funcionando. Sin embargo, ¿alguien sabe qué pasa con el primer intento? Me gustaría hacer que el primero funcione, ya que se asemeja más a cómo está estructurado SQL. ¡Gracias por adelantado!

Nota: Sé que también podemos escribir mysql o dql nativos con Doctrine, pero prefiero el generador de consultas.

EDITAR: A continuación está el código completo

namespace Cyan/CustomerBundle/Repository; use Cyan/CustomerBundle/Entity/Customer; use Doctrine/ORM/EntityRepository; use Doctrine/ORM/Query/Expr/Join; class CustomerRepository extends EntityRepository { public function findCustomerByPhone($username, $phone) { $qb = $this->createQueryBuilder(''c''); $qb->select(''c'') ->innerJoin(''c.phones'', ''p'', Join::ON, $qb->expr()->andx( $qb->expr()->eq(''p.customerId'', ''c.id''), $qb->expr()->eq(''p.phone'', '':phone'') )) ->where(''c.username = :username''); // $qb->select(''c'') // ->innerJoin(''c.phones'', ''p'') // ->where(''c.username = :username'') // ->andWhere(''p.phone = :phone''); $qb->setParameters(array( ''username'' => $username, ''phone'' => $phone->getPhone(), )); $query = $qb->getQuery(); return $query->getResult(); } }


Puedes tener una unión explícitamente así:

$qb->innerJoin(''c.phones'', ''p'', Join::ON, ''c.id = p.customerId'');

Pero necesita usar el espacio de nombres de la clase Join from doctrine:

use Doctrine/ORM/Query/Expr/Join;

O si prefieres así:

$qb->innerJoin(''c.phones'', ''p'', Doctrine/ORM/Query/Expr/Join::ON, ''c.id = p.customerId'');

De lo contrario, la clase Join no se detectará y tu script se bloqueará ...

Aquí el constructor del método innerJoin:

public function innerJoin($join, $alias, $conditionType = null, $condition = null);

Puedes encontrar otras posibilidades (no solo unir "ON", sino también "WITH", etc ...) aquí: http://docs.doctrine-project.org/en/2.0.x/reference/query-builder.html#the-expr-class

EDITAR

Piensa que debería ser:

$qb->select(''c'') ->innerJoin(''c.phones'', ''p'', Join::ON, ''c.id = p.customerId'') ->where(''c.username = :username'') ->andWhere(''p.phone = :phone''); $qb->setParameters(array( ''username'' => $username, ''phone'' => $phone->getPhone(), ));

De lo contrario, creo que estás realizando una combinación de ON y WITH, tal vez el problema.


Voy a responder mi propia pregunta.

  1. innerJoin debe usar la palabra clave "WITH" en lugar de "ON" (la documentación de Doctrine [13.2.6. Helper methods] es inexacta; [13.2.5. La clase Expr] es correcta)
  2. no es necesario vincular claves externas en condición de unión ya que ya están especificadas en la asignación de entidad.

Por lo tanto, lo siguiente funciona para mí

$qb->select(''c'') ->innerJoin(''c.phones'', ''p'', ''WITH'', ''p.phone = :phone'') ->where(''c.username = :username'');

o

$qb->select(''c'') ->innerJoin(''c.phones'', ''p'', Join::WITH, $qb->expr()->eq(''p.phone'', '':phone'')) ->where(''c.username = :username'');