26 Stimmen

Doctrine 2 DQL - Zeilen auswählen, wenn ein Many-to-many-Feld leer ist?

Ich habe zwei Klassen in diesem Beispiel - DeliveryMethod und Country. Sie haben eine Many-to-many-Beziehung zueinander.

Ich möchte alle DeliveryMethods auswählen, denen keine Countries zugeordnet sind.

Ich kann auch das Gegenteil tun, d.h. alle Zustellungsmethoden auswählen, die mindestens ein Land haben.

SELECT m FROM DeliveryMethod m JOIN m.countries

Aber ich kann nicht herausfinden, wie ich eine Auswahl treffen kann, wenn das Länderfeld leer ist. In einfachem SQL würde ich Folgendes tun (deliverymethod_country ist die Verknüpfungstabelle):

SELECT m.* FROM deliverymethods m
LEFT JOIN deliverymethod_country dc ON dc.deliverymethod_id = m.id
WHERE dc.deliverymethod_id IS NULL

Allerdings funktioniert eine DQL-Entsprechung davon nicht, zum Beispiel:

SELECT m FROM DeliveryMethod m LEFT JOIN m.countries WHERE m.countries IS NULL

Ich erhalte diese Fehlermeldung:

[Syntax Error] line 0, col 75: Error: Expected end of string, got 'm'

85voto

flu Punkte 13677

Verwenden Sie Doctrine's is empty

Es wurde speziell dafür entwickelt, nach leeren Assoziationen zu suchen:

$qb->select('m')->from('DeliveryMethods', 'm')->where('m.countries is empty')

Siehe: Doctrine 2 ORM Dokumentation: Doctrine Abfragesprache (Suche nach "ist leer")

23voto

Broncha Punkte 3744

Und was ist damit? Angenommen, $qb ist Ihre Query Builder-Instanz

$qb->select('m')
   ->from('DeliveryMethods','m')
   ->leftJoin('m.countries','c')
   ->having('COUNT(c.id) = 0')
   ->groupBy('m.id');

So erhalten Sie die DeliveryMethods, die mit Ländern verbunden sind, und die Anzahl der verbundenen Länder ist 0

16voto

pleerock Punkte 17230

Es gibt keinen Grund, sich zu verbinden und etwas zu haben. Verwenden Sie einfach SIZE Funktion:

$qb->select('m')
   ->from('DeliveryMethods','m')
   ->where('SIZE(m.countries) = 0');

So erhalten Sie alle Methoden ohne angehängte Länder

0voto

spacemonkey Punkte 1606

NULL-Werte können nicht verknüpft werden, IIRC. Entschuldigung für den Tippfehler auf Twitter, sollte gesagt haben "kann nicht".

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X