Joomla Wählen Sie aus DB UND / ODER-Gruppierung

Jan 26 2021

Ich habe in Joomla keine Anleitung zum Umgang mit solchen Anfragen gefunden:

Ich möchte alle Elemente aus db auswählen, die sind:

Published
AND
(the publish up date is 0000-00-00 00:00:00 or smaller then datenow)
OR
(the publish down date is 0000-00-00 00:00:00 or larger then datenow)

um alle Elemente zu erhalten, die veröffentlicht wurden und deren Datumsangabe innerhalb des Start- / Enddatums der Veröffentlichung liegt oder wenn festgelegte Start- / Endwerte nicht festgelegt sind.

Was ich bisher habe, ist eine einfache Abfrage:

$query->where($db->quoteName('published') . ' = 1 ');
$query->where($db->quoteName('publish_up') . ' = ' . $db->quote('0000-00-00 00:00:00')) ->orWhere($db->quoteName('publish_up') . '<' . $db->quote($date));
$query->where($db->quoteName('publish_down') . ' = ' . $db->quote('0000-00-00 00:00:00')) ->orWhere($db->quoteName('publish_down') . '>' . $db->quote($date));
        

So weit so gut, aber am Ende baut es eine Abfrage wie folgt auf:

SELECT *
FROM `tblname`
WHERE 
(
(`published` = 1  AND `publish_up` = \'0000-00-00 00:00:00\') OR 
(`publish_up`<\'2021-01-26 13:03:07\') OR `publish_down` = \'0000-00-00 00:00:00\') OR 
(`publish_down`>\'2021-01-26 13:03:07\')
ORDER BY ordering ASC

Joomla setzt oder gruppiert die Abfrage nicht so, wie ich sie brauche, die erste ist UND und dann ist alles andere ODER.

Ich bin sicher, es ist eher eine Wissens- / Syntaxlücke als ein Fehler - aber wie ist der richtige Weg, um eine richtige Abfrage zu schreiben, die auf meinen Bedürfnissen basiert?

PS: Die DB-Tabelle stammt aus einer benutzerdefinierten Komponente

Antworten

2 mickmackusa Jan 27 2021 at 07:29

Da 0000-00-00 00:00:00immer weniger als der aktuelle Datums- / Uhrzeitstempel angezeigt wird, verstehe ich Ihre Anforderungen wie folgt:

published = 1
AND
publish_up <= now
AND
(
    publish_down = 0000-00-00 00:00:00
    OR
    publish_down > now
)
  • where()hat einen Standardkleberwert von AND.
  • andWhere()hat einen Standardkleberwert von OR.

Um das in Joomlas Querybuilder zu übersetzen, würden Sie schreiben:

$query ->where( [ $db->quoteName('published') . ' = 1'),
            $db->quoteName('publish_up') . ' <= ' . $db->quote($date), ] ) ->andWhere( [ $db->quoteName('publish_down') . ' = ' . $db->quote('0000-00-00 00:00:00'), $db->quoteName('publish_down') . ' > ' . $db->quote($date)
        ]
    )

Ihre erforderliche Logik stimmt perfekt mit den Standardklebstoffen der Methoden überein, sodass keine Kleberdeklarationen erforderlich sind.

Gerendertes SQL:

WHERE
(`published` = 1 AND `publish_up` <= '2021-01-26 13:03:07') AND
(`publish_down` = '0000-00-00 00:00:00' OR `publish_down` > '2021-01-26 13:03:07')

Anmerkungen:

  1. Das Verketten oder Nichtverketten der Methodenaufrufe hat keinen Einfluss auf die Art und Weise, wie die SQL generiert wird. Mit anderen Worten, Sie gewinnen oder verlieren keine Klammern, wenn Sie eine "Kette" von Methodenaufrufen fortsetzen oder unterbrechen.

  2. Ich würde verwenden, CURRENT_TIMESTAMPwenn Sie $datenicht das sind, was ich denke. Mögen:

    $db->quoteName('publish_up') . ' <= CURRENT_TIMESTAMP',
    
  3. Hier ist ein weiterer meiner Beiträge, der sich mit verschiedenen Kombinationen der Syntax zum Erstellen von Gebäuden befasst .