Joomla Wählen Sie aus DB UND / ODER-Gruppierung
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
Da 0000-00-00 00:00:00
immer 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 vonAND
.andWhere()
hat einen Standardkleberwert vonOR
.
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:
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.
Ich würde verwenden,
CURRENT_TIMESTAMP
wenn Sie$date
nicht das sind, was ich denke. Mögen:$db->quoteName('publish_up') . ' <= CURRENT_TIMESTAMP',
Hier ist ein weiterer meiner Beiträge, der sich mit verschiedenen Kombinationen der Syntax zum Erstellen von Gebäuden befasst .