Rejoindre sous-requête avec DBAL de doctrine 2
Je suis refactoring Zend Framework 2 application à la doctrine de l'usage de 2,5 DBAL au lieu de Zend_DB (ZF1). J'ai le texte suivant Zend_Db requête:
$subSelect = $db->select()
->from('user_survey_status_entries', array('userSurveyID', 'timestamp' => 'MIN(timestamp)'))
->where('status = ?', UserSurveyStatus::ACCESSED)
->group('userSurveyID');
$select = $db->select()
//$selectColNames contains columns both from the main query and
//the subquery (e.g. firstAccess.timestamp AS dateFirstAccess).
->from(array('us' => 'user_surveys'), $selectColNames)
->joinLeft(array('firstAccess' => $subSelect), 'us.userSurveyID = firstAccess.userSurveyID', array())
->where('us.surveyID = ?', $surveyID);
Cette résultats dans la suite de requête MySQL:
SELECT `us`.`userSurveyID`,
//More columns from main query `us`
`firstAccess`.`timestamp` AS `dateFirstAccess`
FROM `user_surveys` AS `us`
LEFT JOIN (
SELECT `user_survey_status_entries`.`userSurveyID`,
MIN(timestamp) AS `timestamp`
FROM `user_survey_status_entries`
WHERE (status = 20)
GROUP BY `userSurveyID`
) AS `firstAccess` ON us.userSurveyID = firstAccess.userSurveyID
WHERE (us.surveyID = '10')
Je ne peux pas comprendre comment rejoindre la sous-requête à l'aide de la doctrine de 2,5 générateur de requêtes. Dans la requête principale, j'ai besoin de sélectionner les colonnes à partir de la sous-requête.
J'ai lu ici que la doctrine ne prend pas en charge la participation des sous-requêtes. Si c'est toujours vrai, puis-je écrire cette requête d'une autre manière à l'aide de la requête SQL builder de la doctrine DBAL? Natif SQL ne peut pas être une bonne solution pour moi, que cette requête sera dynamiquement étendu plus tard dans le code.
- Récupérer le résultat de votre sous-sélection puis l'utiliser comme paramètre de votre sélection.
- le résultat de celle-ci sera un tableau avec des milliers d'éléments, je ne pense pas que c'est viable pour récupérer et l'utiliser comme un paramètre dans la requête principale.
- Est-ce DQL ou SQL que vous essayez de construire?
- Je suis en train de construire SQL. La requête est finalement utilisé pour des données csv à l'exportation, après l'ajout d'un tas de choses qui ne figurent pas ici.
- C'est donc DBAL liées (merci de ne faire que ce soit clair dans la question). Est le générateur de requête strictement nécessaire dans ce processus? Étant donné qu'il n'a pas vraiment de garantie de portabilité, je vous suggère de les supprimer progressivement complètement. Je ne vois pas de support pour rejoindre les non-tables dans le QB: github.com/doctrine/dbal/blob/... Si votre but est portable requêtes par l'intermédiaire d'un générateur de requêtes (SQL), puis le ZF2 générateur de requête peut en effet être une meilleure solution, bien que tous les moteurs permettent de se joindre à des sous-requêtes.
- Merci, maintenant, je précise que ceci est DBAL liées à la question. Je dois utiliser un générateur de requête, la requête devient très complexe (non illustré ci-dessus). Je vais vous donner doctrine DBAL un dernier coup et de passer à l'ZF2 générateur de requête, en cas d'échec.
- J'ai fait une demande de fonctionnalité pour l'assemblage de sous-requêtes dans DBAL, il peut être considéré pour la version 3.0: github.com/doctrine/dbal/issues/2305
- cette solution peut être très utile: stackoverflow.com/a/46663949/2450812
Vous devez vous connecter pour publier un commentaire.
J'ai trouvé une solution en adaptant cette DQL exemple à DBAL. L'astuce consiste à obtenir le SQL brut de la sous-requête, l'envelopper dans des crochets, et se joindre à elle. Les paramètres utilisés dans la sous-requête doit être défini dans la requête principale:
->leftJoin('us', sprintf('(%s)', $subSelect->getSQL()), 'firstAccess', 'us.userSurveyID = firstAccess.userSurveyID')
Le troisième argument doit êtreExpr\Join::ON
ouExpr\Join::WITH.
Expr\Join::ON
etExpr\Join::WITH
s'applique uniquement à laORM
des espaces de QueryBuilder. par exemple,\Doctrine\ORM\Query\Expr\Join
pour une utilisation avec\Doctrine\ORM\QueryBuilder::join
autonomeDBAL
ne dispose pas d'unJoin
objet. LeDBAL
jointures sont implicitement toujours unON
conditionnelle. Voir: doctrine-project.org/api/dbal/2.5/... et doctrine-project.org/api/orm/2.5/...Pour répondre à cette partie de votre question:
Vous pouvez le faire de 2 constructeur de requête d'instances et d'utiliser le DQL de la seconde à l'intérieur d'une clause de votre première requête. Un exemple:
Vérifier exemples ici ou ici ou trouver plus à l'aide de Google
u1
etu2
et puis neandWhere('u1.id = u2.id');
.i
eti2
ou de lire ce blog, où ilsm
etsm
et puis ne'm.name = sm.name'
. Vous devriez être en mesure de le comprendre, avec ces exemples...where
fonction, mais pas dans leleftJoin
fonction. Comme mentionné par le Ocramius ici, je pense que la doctrine fournit pas de solution sans l'aide de SQL natif. Je pourrais avoir à utiliser le zend framework 2 constructeur de requête à la place...$qb2->getDQL()
dans la réponse: la question a été modifiée pour préciser que c'est sur le DBAL, pas l'ORM 😉