2017-10-27 17 views
1

Ich habe eine Entität namens Company. Die Zuordnungen werden wie folgt zugeordnet:Doktrinenentitäten nach ihren Zuordnungen filtern

manyToOne: 
    headCompany: 
     targetEntity: CompanyEntity 
     inversedBy: headCompany 
oneToMany: 
    subsidiaries: 
     targetEntity: CompanyEntity 
     mappedBy: headCompany 

Alles funktioniert gut. Ein Unternehmen kann Tochterunternehmen eines anderen Unternehmens sein und/oder eigene Tochtergesellschaften haben.

Jetzt muss ich müssen Unternehmen filtern, die Head-Unternehmen von anderen sind, oder Unternehmen, die Tochtergesellschaften haben.

Ich kann das direkt mit SQL tun:

SELECT c.id, COUNT(s.headCompany_id) subsidiaries FROM companies c LEFT JOIN companies s ON s.headCompany_id = c.id GROUP BY c.id HAVING subsidiaries > 0 

dies so etwas wie Resultierende:

+----+--------------+ 
| id | subsidiaries | 
+----+--------------+ 
| 1 | 3   | 
+----+--------------+ 
| 5 | 2   | 
+----+--------------+ 

Dann Unternehmen 1 und 5 würden meinen Filter passen, weil sie beide Tochtergesellschaften haben.

Wie kann ich das gleiche Ergebnis mit Doctrine Query Builder erreichen?

Meine Versuche waren:

$query = $qb->select('e') 
    ->from('CompanyEntity', 'e') 
    ->orderBy('e.id', 'ASC') 
    ->join('e.headCompany', 'h') 
    ->addSelect("COUNT(h.id) as subsidiaries") 
    ->groupBy("e.id") 
    ->having("subsidiaries > 0"); 

Diese man die Tochtergesellschaften zurückkommt, nicht die Kopf Unternehmen.

->where($qb->expr()->isNotNull("e.subsidiaries"))

Und das ist offenbar nicht durch Lehre erlaubt.

Antwort

0

Wie wäre es die Klausel, wählen Unternehmen Reverse beitreten und mit Tochtergesellschaften dann anwenden Filter auf Anzahl der Tochtergesellschaften für jedes Unternehmen im Zusammenhang beitreten

$query = $qb->select('h,s') 
    ->from('CompanyEntity', 'h') 
    ->join('h.subsidiaries', 's') 
    ->addSelect("COUNT(s.id) AS HIDDEN subsidiaries") 
    ->groupBy("h.id") 
    ->orderBy('h.id', 'ASC') 
    ->having("subsidiaries > 0"); 

Wie Sie sqlmode =>only_full_group_by verwenden Sie alle Spalten von Unternehmen nicht auswählen können, es sei denn, sie sind in der Gruppe vorhanden, also wählen Sie in select() welche Spalten zurückgeben.

$query = $qb->select('h.id') 
    ->from('CompanyEntity', 'h') 
    ->join('h.subsidiaries', 's') 
    ->addSelect("COUNT(s.id) AS HIDDEN subsidiaries") 
    ->groupBy("h.id") 
    ->orderBy('h.id', 'ASC') 
    ->having("subsidiaries > 0"); 

Gemäß offizieller Dokumentation „ONLY_FULL_GROUP_BY Anfragen ablehnen, für die die Auswahlliste, HAVING Bedingung oder ORDER BY-Liste nicht aggregierten Spalten beziehen, die in den GROUP BY-Klausel weder benannt noch funktionell abhängig von (eindeutig bestimmt durch) GROUP BY-Spalten. "

+0

Vielen Dank für Ihre Zeit, aber es didn‘ t work: 'SQLSTATE [42000]: Syntaxfehler oder Zugriffsverletzung: 1055 Der Ausdruck # 12 der SELECT-Liste befindet sich nicht in der GROUP BY-Klausel und enthält die nicht aggregierte Spalte 'table.c1_.id', die funktional nicht von Spalten in der GROUP BY-Klausel abhängig ist ; Dies ist nicht kompatibel mit sql_mode = only_full_group_by'. Stimmt es, in diesem Zusammenhang "Tochtergesellschaften" beizutreten? Es ist keine tatsächliche Spalte, nur eine Doktrin-Assoziation. –

+0

Gleiches Problem :-(SQLSTATE [42000]: Syntaxfehler oder Zugriffsverletzung: 1055 Ausdruck # 12 der SELECT-Liste ist nicht in der GROUP BY-Klausel und enthält nichtaggregierte Spalte 'table_dev.c0_.id', die nicht funktional von Spalten in GROUP BY-Klausel, das ist inkompatibel mit sql_mode = only_full_group_by' –

+0

@ Vinícius Ich habe meine Antwort aktualisiert, wie Sie ONLY_FULL_GROUP_BY-Modus verwenden –

0

Sie sollten einen Auftrag von Fall zu verwenden, ein bisschen wie diese in der Lage sein:

$query = $qb->select('e') 
    ->from('CompanyEntity', 'e') 
    ->join('e.headCompany', 'h') 
    ->addSelect("(CASE WHEN COUNT(h.id) > 0 THEN 1 ELSE 0 END) as sort_sub") 
    ->groupBy("e.id") 
    ->orderBy("sort_sub"); 

Sie können in diesem Thread mehr darüber lesen: How to ORDER BY CASE in Doctrine2 (Symfony2)

+0

Die '-> orderBy (" sort_sub ");' das gab Fehler, diese Methode gibt die Firmen zurück, die _ARE_ Tochtergesellschaften, nicht Firmen, die Tochtergesellschaften _HAVE_ haben, nur wie mein erster Versuch, leider. Danke für Ihre Zeit. –