Selección de Joomla de la agrupación DB AND / OR

Jan 26 2021

No encontré ninguna guía sobre cómo manejar tales consultas en Joomla:

Me gustaría seleccionar todos los elementos de db que son:

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)

para obtener todos los elementos que se publican y la fecha actual se encuentra dentro de la fecha de inicio / finalización de publicación o cuando los valores de inicio / finalización establecidos no están establecidos.

Lo que tengo hasta ahora es una consulta simple:

$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));
        

Hasta ahora todo bien, pero al final genera una consulta como esta:

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 no establece ni agrupa la consulta como la necesito, la primera es Y y luego todo lo demás es OR.

Estoy seguro de que es solo una brecha de conocimiento / sintaxis en lugar de un error, pero ¿cómo es la forma correcta de escribir una consulta adecuada según mis necesidades?

PD: la tabla DB es de un componente personalizado

Respuestas

2 mickmackusa Jan 27 2021 at 07:29

Debido a 0000-00-00 00:00:00que siempre será menor que el sello de fecha y hora actual, entiendo sus requisitos como:

published = 1
AND
publish_up <= now
AND
(
    publish_down = 0000-00-00 00:00:00
    OR
    publish_down > now
)
  • where()tiene un valor de pegamento predeterminado de AND.
  • andWhere()tiene un valor de pegamento predeterminado de OR.

Para traducir eso al generador de consultas de Joomla, escribirías:

$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)
        ]
    )

Su lógica requerida se alinea perfectamente con los pegamentos predeterminados de los métodos, por lo que no son necesarias declaraciones de pegamento.

SQL renderizado:

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')

Notas:

  1. Encadenar o no encadenar las llamadas al método no afecta la forma en que se genera el sql. En otras palabras, no gana ni pierde ningún paréntesis por continuar o romper una "cadena" de llamadas a métodos.

  2. Lo usaría a CURRENT_TIMESTAMPmenos que tu $dateno sea lo que creo que es. Como:

    $db->quoteName('publish_up') . ' <= CURRENT_TIMESTAMP',
    
  3. Aquí hay otra de mis publicaciones que profundiza en diferentes combinaciones de sintaxis de construcción .