Wie wähle ich eine bestimmte Abfrage mit dem Symfony2 Doctrine Query Builder aus?


74

Ich habe diesen Symfony-Code, in dem alle Kategorien abgerufen werden, die sich auf einen Blog-Abschnitt in meinem Projekt beziehen:

$category = $catrep->createQueryBuilder('cc')
    ->Where('cc.contenttype = :type')
    ->setParameter('type', 'blogarticle')
    ->getQuery();

$categories = $category->getResult();

Dies funktioniert, aber die Abfrage enthält Duplikate:

Test Content
Business
Test Content

Ich möchte den DISTINCTBefehl in meiner Abfrage verwenden. Die einzigen Beispiele, die ich gesehen habe, erfordern, dass ich unformatiertes SQL schreibe. Ich möchte dies so weit wie möglich vermeiden, da ich versuche, meinen gesamten Code gleich zu halten, damit alle die von Symfony2 / Doctrine bereitgestellte QueryBuilder-Funktion verwenden.

Ich habe versucht distinct(), meiner Abfrage Folgendes hinzuzufügen :

$category = $catrep->createQueryBuilder('cc')
    ->Where('cc.contenttype = :type')
    ->setParameter('type', 'blogarticle')
    ->distinct('cc.categoryid')
    ->getQuery();

$categories = $category->getResult();

Dies führt jedoch zu folgendem Fehler:

Schwerwiegender Fehler: Aufruf der undefinierten Methode Doctrine \ ORM \ QueryBuilder :: unique ()

Wie sage ich Symfony, dass sie eine bestimmte auswählen soll?


2
Sie sollten einen booleschen Wert an die Funktion different () übergeben. doi-project.org/api/orm/2.2/…
Omn

Antworten:


31

du könntest schreiben

select DISTINCT f from t;

wie

select f from t group by f;

Die Sache ist, dass ich gerade selbst in die Lehre einsteige, also kann ich Ihnen keine wirkliche Antwort geben. Aber Sie können, wie oben gezeigt, eine eindeutige Gruppe mit simulieren und diese in Doktrin umwandeln . Wenn Sie weitere Filter hinzufügen möchten, verwenden Sie HAVINGnach Gruppieren nach.


1
@mickburkejnr Bis Sie eine ORDER-Klausel hinzufügen. :(
undefiniert

1
@xyu Ich weiß, es ist nicht ideal, oder? Warum sollten wir mit so etwas schwerfällig sein? Warum kann es nicht einfach funktionieren?
Mickburkejnr

1
@mickburkejnr Die Gruppierung erfolgt vor der Bestellung in SQL.
undefiniert

11
Dies ist nur dann die richtige Antwort, wenn Sie eine SQL-Anweisung und nicht den Query Builder verwenden. Dies sollte nicht als Antwort markiert werden. Die von @skler gegebene Lösung ist die richtige.
Tom T

2
(Alter Kommentar, ich weiß ...). @ Tom T: Eigentlich ist diese Antwort gültig. Anstatt zu versuchen, das eigentliche DISTINCT Schlüsselwort zu verwenden, simulieren Sie es mithilfe von GROUP BYQueryBuilder. Er gab jedoch kein Beispiel. Hier ist eine einfache:$q = $db->createQueryBuilder(); $q->select('f')->from('t', 't')->groupBy('f');
user128216

170

Das funktioniert:

$category = $catrep->createQueryBuilder('cc')
        ->select('cc.categoryid')
        ->where('cc.contenttype = :type')
        ->setParameter('type', 'blogarticle')
        ->distinct()
        ->getQuery();

$categories = $category->getResult();

54

Wenn Sie die Anweisung "select ()" verwenden, können Sie Folgendes tun:

$category = $catrep->createQueryBuilder('cc')
    ->select('DISTINCT cc.contenttype')
    ->Where('cc.contenttype = :type')
    ->setParameter('type', 'blogarticle')
    ->getQuery();

$categories = $category->getResult();

-1

Öffnen Sie einfach Ihre Repository-Datei, fügen Sie diese neue Funktion hinzu und rufen Sie sie in Ihrem Controller auf:

 public function distinctCategories(){
        return $this->createQueryBuilder('cc')
        ->where('cc.contenttype = :type')
        ->setParameter('type', 'blogarticle')
        ->groupBy('cc.blogarticle')
        ->getQuery()
        ->getResult()
        ;
    }

Dann in Ihrem Controller:

public function index(YourRepository $repo)
{
    $distinctCategories = $repo->distinctCategories();


    return $this->render('your_twig_file.html.twig', [
        'distinctCategories' => $distinctCategories
    ]);
}

Viel Glück!


Was meinst du mit "keiner hat funktioniert"? Was passiert stattdessen? Warum sollte das ein Problem von Symfony sein, während der Abfrage-Generator Teil von Doctrine ist?
Nico Haase

@NicoHaase, da beim Erstellen eines neuen Symfony-Projekts über Composer die neueste Version von Twig and Doctrine installiert wird, habe ich erwähnt, dass meine Lösung mit Symfony5 und der damit verbundenen Doctrine-Version getestet wird. Hoffe es ist jetzt klarer.
Ali
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.