sql >> Database >  >> RDS >> Mysql

Doctrine QueryBuilder:ManyToOne-relatie waarbij meer dan één subEntiteit moet overeenkomen

Je doet het niet goed, je vergelijkt labels en waarden met de laatste filterwaarden omdat de tijdelijke aanduidingen :label , :value gebruikt in de query zijn niet uniek voor elke lus-iteratie, dus alle clausules die door de lus worden gegenereerd, komen overeen met het laatste label en de laatste waarde.

Om de banen te krijgen waarvan elke eigenschap overeenkomt met de verstrekte filters, kunt u een beetje schrijven zoals onderstaande doctrine-query.

Eerst verzamelt het alle labels en waarden in een aparte array en dan komt het overeen met de eigenschappen van de job door IN() te gebruiken bewerking, als laatste om de banen te krijgen waarvan de eigenschappen overeenkomen met alle filters die u nodig hebt om aggregatie te bouwen om de overeenkomende resultaten te tellen en moet gelijk zijn aan het aantal filters

$qb =  $this->getDoctrine()
            ->getRepository('AppBundle:Job')
            ->createQueryBuilder('job')
            ->innerJoin('job.properties','p');
$labels = array();
$values = array();
foreach($filters as $label => $value)
{
    $labels[] = $label;
    $values[] = $value;
}
$qb->addSelect('COUNT(DISTINCT  p.id) AS total_properties')
   ->andWhere('p.label IN (:labels)')
   ->andWhere('p.value IN (:values)')
   ->addGroupBy('job.id')
   ->having('total_properties = '.count($filters))
   ->setParameter('labels',$labels)
   ->setParameter('values',$values)
   ->getQuery()
   ->getResult();



  1. MySQL:selecteer zoekopdracht, in stappen van 5 minuten

  2. JPA-toewijzingsweergaven en tabellen met overerving

  3. Een MySQL INSERT/UPDATE-instructie voorbereiden met DEFAULT-waarden

  4. Verbinding maken met een MySQL-server via C++