Je souhaite sélectionner des articles de commande parmi toutes les commandes avec un article spécifique. En SQL, je le ferais comme ceci:
SELECT DISTINCT i.id, i.name, order.name
FROM items i
JOIN orders o ON i.order_id=o.id
WHERE o.id IN (
SELECT o2.id FROM orders o2
JOIN items i2 ON i2.order_id=o2.id AND i2.id=5
)
AND i.id != 5
ORDER BY o.orderdate DESC
LIMIT 10
Comment pourrais-je faire cette requête avec le générateur de requêtes?
Voici comment je l'essayerais:
/** @var Doctrine\ORM\EntityManager $em */
$expr = $em->getExpressionBuilder();
$em->createQueryBuilder()
->select(array('DISTINCT i.id', 'i.name', 'o.name'))
->from('Item', 'i')
->join('i.order', 'o')
->where(
$expr->in(
'o.id',
$em->createQueryBuilder()
->select('o2.id')
->from('Order', 'o2')
->join('Item',
'i2',
\Doctrine\ORM\Query\Expr\Join::WITH,
$expr->andX(
$expr->eq('i2.order', 'o2'),
$expr->eq('i2.id', '?1')
)
)
->getDQL()
)
)
->andWhere($expr->neq('i.id', '?2'))
->orderBy('o.orderdate', 'DESC')
->setParameter(1, 5)
->setParameter(2, 5)
;
Je n'ai pas testé cela bien sûr, et j'ai fait quelques hypothèses sur vos modèles. Problèmes possibles:
En conclusion, cela peut ne pas fonctionner du premier coup, mais cela vous mettra sûrement sur la bonne voie. Dites-nous ensuite la bonne réponse finale à 100%.
Juste pour éviter la confusion du dernier commentaire posté par clang1234.
l'exemple de requête dql fonctionne vraiment. Il est vrai que The expr-> in () convertira le second paramètre en un tableau, dans ce cas la chaîne dql. Ce qu'il fait, il crée simplement un tableau avec la chaîne de requête dql comme premier élément. C'est exactement ce que l'Expr\Func attend, un tableau. C'est un peu plus profond dans le code Doctrine 2 que l'élément de tableau de chaîne de requête dql sera géré correctement. (Voir la méthode getInExpression de DBAL/Platforms/AbstractPlatform.php pour plus de détails, le tableau est implosé dans DANS())