Joomla Selecionar do agrupamento DB E / OU

Jan 26 2021

Não encontrei nenhum guia sobre como lidar com essas consultas no Joomla:

Eu gostaria de selecionar todos os itens do banco de dados que são:

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 obter todos os itens que são publicados e os dados agora estão dentro da data de início / término da publicação ou quando os valores de início / término definidos não estão definidos.

O que tenho até agora é uma consulta simples:

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

Até aqui tudo bem, mas no final ele cria uma 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 não define ou agrupa a consulta como eu preciso, o primeiro é AND e então todo o resto é OR.

Tenho certeza de que é apenas uma lacuna de conhecimento / sintaxe em vez de um bug - mas como é a maneira correta de escrever uma consulta adequada com base nas minhas necessidades?

PS: a tabela DB é de um componente personalizado

Respostas

2 mickmackusa Jan 27 2021 at 07:29

Como 0000-00-00 00:00:00sempre será menor do que o carimbo de data / hora atual, estou entendendo seus requisitos como:

published = 1
AND
publish_up <= now
AND
(
    publish_down = 0000-00-00 00:00:00
    OR
    publish_down > now
)
  • where()tem um valor de colagem padrão de AND.
  • andWhere()tem um valor de colagem padrão de OR.

Para traduzir isso para o construtor de consultas do Joomla, você escreveria:

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

Sua lógica necessária se alinha perfeitamente com as colas padrão dos métodos, portanto, nenhuma declaração de colagem é necessária.

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. Encadear ou não as chamadas de método não afeta a maneira como o sql é gerado. Em outras palavras, você não ganha ou perde parênteses ao continuar ou quebrar uma "cadeia" de chamadas de método.

  2. Eu estaria usando, a CURRENT_TIMESTAMPmenos que você $datenão fosse o que eu penso que é. Como:

    $db->quoteName('publish_up') . ' <= CURRENT_TIMESTAMP',
    
  3. Aqui está outra de minhas postagens que investiga diferentes combinações de onde a sintaxe de construção .