2017-08-09 5 views
-1

Ich muss diese Abfrage mit Doctrine schreiben. Wie kann ich es mit QueryBuilder aufschreiben?JOIN zwei SELECTs mit Doctrine

SELECT charges.id, charges.currency, charges.total_transactions, 
charges.total_volume, charges.commission, refunds.total_payouts 
FROM 
(SELECT ...very long query...) charges 
LEFT JOIN 
(SELECT ...very long query...) refunds 
ON charges.id = refunds.id AND charges.currency = refunds.currency 
+0

Sie die verwenden können [Abfrage-builder] (http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/abfrage-bui lder.html) um diese Abfrage zu erstellen. – thhan

+0

@than, ich kann dort keine Informationen für meinen Fall finden. Nur für SELECT aus Tabelle (entity), nicht aus zwei verbundenen SELECTs. Wenn Sie wissen, wie man das macht, können Sie ein Beispiel geben? –

+0

Sie können zwei vorherige queryBuilder als Quelle für Ihre 'from' verwenden. – Veve

Antwort

1

Sie können Native SQL und Karte Ergebnisse Einheiten verwenden:

use Doctrine\ORM\Query\ResultSetMapping; 

$rsm = new ResultSetMapping; 
$rsm->addEntityResult('AppBundle:Charges', 'charges') 
    ->addEntityResult('AppBundle:Refunds', 'refunds') 
    ->addFieldResult('charges', 'id', 'id') 
    ->addFieldResult('charges', 'currency', 'currency') 
    ->addFieldResult('charges', 'total_transactions', 'total_transactions') 
    ->addFieldResult('charges', 'total_volume', 'total_volume') 
    ->addFieldResult('charges', 'commission', 'commission') 
    ->addFieldResult('refunds', 'total_payouts', 'total_payouts') 
; 

$sql = " 
    SELECT 
     charges.id, 
     charges.currency, 
     charges.total_transactions, 
     charges.total_volume, 
     charges.commission, 
     refunds.total_payouts 
    FROM 
     (SELECT ...very long query...) charges 
    LEFT JOIN 
     (SELECT ...very long query...) refunds ON charges.id = refunds.id AND charges.currency = refunds.currency 
    WHERE some_field = ? 
"; 

$query = $this->getEntityManager()->createNativeQuery($sql, $rsm); 
$query->setParameter(1, $name); 
$entities = $query->getResult(); 
+0

Thx, Mann. Ich denke, das ist die einzige mögliche Lösung mit Doctrine in diesem Fall. –

1

können Sie DQL wie folgt verwenden:

$dql = "SELECT ..."; 
$q = $entityManager->createQuery($dql)->setParameters($arrayParameters); 
$result = $q->execute(); 

oder QueryBuilder für jede Unterabfrage, wie:

// subquery 1 
$subQuery1 = $entityManager->createQueryBuilder() 
    ->select('...') 
    ->from('...') 
    ->getDQL() 
; 
// subquery 2 
$subQuery2 = ... 
// etc 
// ... 
// main query 
$query = $entityManager->createQueryBuilder() 
    ->select('...') 
    ->from('...', $subQuery1) 
    ->leftJoin('...', $subQuery1->getDQL()), 
    ->where() 
; 

PS: Ich versuche nur für Sie Kern bieten ... hoffe du hast jetzt eine ahnung ...

+0

Sind Sie sicher, dass die Lösung mit' QueryBuilder' funktionieren kann? Weil, wenn ich erzeugte Abfrage ausführe, es die Ausnahme wirft, dass "Klasse" SELECT "nicht auf Spalte 195" gerade definiert wird, wo die Hauptabfrage 'FROM' versucht, Unteranfrage1 zu benutzen (... FROM AUSWAHL ...). –

0

Jetzt habe ich herausgefunden, dass es unmöglich ist.

Kommentar von stof erstellt:

DQL ist über Objekte abfragen. Die Unterstützung von Subselects in der FROM-Klausel bedeutet, dass der DQL-Parser nicht mehr in der Lage ist, die Ergebnismengenzuordnung zu erstellen (da die von der Unteranfrage zurückgegebenen Felder möglicherweise nicht mehr mit dem Objekt übereinstimmen).

Aus diesem Grund kann es nicht unterstützt werden (unterstützt nur für den Fall, dass Sie die Abfrage ohne die Hydrierung ausführen, ist ein No-go IMO, da das Parsing der Abfrage abhängig vom Ausführungsmodus sein muss).

In Ihrem Fall ist die beste Lösung wahrscheinlich stattdessen eine SQL-Abfrage auszuführen (wie Sie einen skalaren bekommen, müssen Sie die ORM Trink sowieso nicht brauchen)

Quelle: https://github.com/doctrine/doctrine2/issues/3542