it-swarm.com.de

JDatabase JOIN für mehrere Werte

Wie lautet die JDatabase-Syntax für eine JOIN-Anweisung, die zwei Tabellen für eine Variable verknüpft, die entweder gleich x oder null ist? ZB verbindet es auf mehreren Werten.

Ich habe einige Beispiele gefunden, die mir zeigen, dass Sie dies in normalem SQL tun können, aber ich weiß nicht, wie sich das in JDatabase-Syntax umsetzt.

Meine Abfrage funktioniert derzeit, wenn die Variable (a.animal) gleich b.id ist, aber ich muss sie auch verbinden, wenn die Variable (a.animal) leer ist.

$query1 = $db->getQuery(true)
    ->select ($db->quoteName(array('a.date','a.reminder','a.type','a.animal','a.mob')))
    ->select ($db->quoteName('b.nameandid') .'AS'. $db->quote('animalname'))    
    ->from ($db->quoteName('app_reminders', 'a'))    
    ->join('INNER', $db->quoteName('app_animal', 'b') . 'ON (' .$db->quoteName('a.animal'). 'LIKE' .$db->quoteName('b.id').')')
    ->where ($db->quoteName('a.date') . '>=' . 'NOW()', 'AND')    
    ->where ($db->quoteName('a.user_id') . 'LIKE' . $db->quote($userid));
3
Hannah Smith

In Ihrer ON -Anweisung sollten Sie mehrere Bedingungen hinzufügen können, die durch AND und OR kombiniert werden. So etwas sollte den Trick machen:

->join('INNER', $db->quoteName('app_animal', 'b') . 'ON (' .$db->quoteName('a.animal'). 'LIKE' .$db->quoteName('b.id').' OR ' . $db->quoteName('a.animal') . ' IS NULL)')
3
fruppel

Ich habe ein paar Bedenken und Verbesserungen, aber ich gehe zuerst direkt zum Code und erkläre ihn anschließend.

Sie möchten eine Abfrage generieren, die wie folgt dargestellt wird:

SELECT a.date, a.reminder, a.type, a.animal, a.mob, b.nameandid AS 'animalname'
FROM app_reminders a
LEFT JOIN app_animal b ON a.animal = b.id
WHERE a.date >= NOW() AND a.user_id = 3

Beachten Sie, dass mein JOIN und das JOIN in der Frage Ihrer verknüpften StackOverflow-Seite LEFT JOIN Verwenden. Das OP in dieser Frage möchte nur Zeilen mit Werten in allen verbundenen Tabellen. Die Antwort verwendet JOIN (regulärer Join aka INNER JOIN). Dies ignoriert Zeilen, die null als Join-Wert haben.

Du willst etwas anderes. Sie möchten, dass die Zeilen aus der ersten Tabelle unabhängig davon, ob die zweite Tabelle einen qualifizierenden Wert enthält, in der Zeile verknüpft werden. Dafür möchten Sie LEFT JOIN. Hier ist ein SQLFiddle Demo , wenn Sie herumspielen und die Ergebnisse der Joins vergleichen möchten. (Wenn dies nicht die Aktion ist, die Sie suchen, sollten Sie in der Lage sein, über diesen Link auszudrücken, was nicht ganz richtig ist.) Mit LEFT JOIN Müssen Sie die zusätzliche Bedingung nicht hinzufügen, um IS NULL.

Nebenbei ...

  1. Sie verwenden den Operator LIKE, jedoch ohne die Platzhalter % Oder _. Es gibt also keinen Grund, LIKE zu schreiben. Einfach zu = Vereinfachen.
  2. Während date und type mysql SCHLÜSSELWÖRTER sind, sind sie nicht RESERVIERTE SCHLÜSSELWÖRTER MÜSSEN nicht in Backticks gewickelt werden. Dies gilt auch für alle anderen Spalten und Tabellennamen. Sie können qn()/quoteName() für alle diese Entitäten verwenden, aber dies fügt Ihrer Abfragesyntax und Ihrem Code nur noch mehr Schwung hinzu.
  3. Um die Lesbarkeit Ihrer Abfrage zu verbessern, müssen Sie auf beiden Seiten Ihrer Vergleichsoperatoren ein einzelnes Leerzeichen einfügen. (z. B. 'LIKE' ist besser als ' LIKE ')
  4. Geben Sie als Sicherheitsmaßnahme die Variable $userid Als Ganzzahl (int) Ein, wenn Sie sie auf Ihre Abfrage anwenden. Ganzzahlige Werte müssen nicht in Anführungszeichen gesetzt werden.
  5. Aus persönlichen Gründen, um die Lesbarkeit/das Codeverständnis zu verbessern, versuche ich, doppelte Methodenaufrufe als Verkettungstechnik für eine einzelne Klausel zu vermeiden. Mein vorgeschlagenes Joomla-Snippet verwendet nur einen select() und einen where() Aufruf. (Beim Verknüpfen mehrerer Tabellen ist das Vorhandensein mehrerer join() -Aufrufe logisch/intuitiv.)

Joomla-Syntax (keine Anführungszeichen genannt):

$query = $db->getQuery(true)
            ->select("a.date, a.reminder, a.type, a.animal, a.mob, b.nameandid AS 'animalname'")
            ->from("app_reminders a")
            ->joinLeft("app_animal b ON a.animal = b.id")
            ->where("a.date >= NOW() AND a.user_id = " . (int)$userid);

p.s. Wenn Sie LIKE tatsächlich mit Platzhalterzeichen verwenden möchten, zeigt Ihnen dieser Beitrag den sicheren Weg - bezogen auf die Joomla-Dokumentation.

1
mickmackusa