Pilih Joomla dari pengelompokan DB DAN / ATAU

Jan 26 2021

Saya tidak menemukan panduan apa pun tentang cara menangani pertanyaan seperti itu di Joomla:

Saya ingin memilih semua item dari db yaitu:

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)

untuk mendapatkan semua item yang diterbitkan dan tanggal sekarang berada dalam tanggal mulai / akhir publikasi atau ketika nilai awal / akhir yang ditetapkan tidak ditetapkan.

Apa yang saya miliki sejauh ini adalah pertanyaan sederhana:

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

Sejauh ini bagus tetapi pada akhirnya itu membangun kueri seperti:

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 tidak mengatur atau mengelompokkan kueri saat saya membutuhkannya, yang pertama adalah AND dan kemudian yang lainnya adalah OR.

Saya yakin ini hanya celah pengetahuan / sintaks daripada bug - tetapi bagaimana cara yang benar untuk menulis kueri yang tepat berdasarkan kebutuhan saya?

PS: Tabel DB berasal dari komponen kustom

Jawaban

2 mickmackusa Jan 27 2021 at 07:29

Karena 0000-00-00 00:00:00akan selalu kurang dari cap tanggal waktu saat ini, saya memahami kebutuhan Anda sebagai:

published = 1
AND
publish_up <= now
AND
(
    publish_down = 0000-00-00 00:00:00
    OR
    publish_down > now
)
  • where()memiliki nilai lem default AND.
  • andWhere()memiliki nilai lem default OR.

Untuk menerjemahkannya ke pembuat kueri Joomla, Anda harus menulis:

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

Logika yang Anda perlukan benar-benar selaras dengan lem default metode, jadi tidak perlu deklarasi lem.

SQL yang dirender:

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

Catatan:

  1. Merangkai atau tidak merangkai panggilan metode tidak memengaruhi cara sql dibuat. Dengan kata lain, Anda tidak akan mendapatkan atau kehilangan tanda kurung apa pun dari melanjutkan atau memutus "rantai" panggilan metode.

  2. Saya akan menggunakan CURRENT_TIMESTAMPkecuali Anda $datetidak seperti yang saya pikirkan. Suka:

    $db->quoteName('publish_up') . ' <= CURRENT_TIMESTAMP',
    
  3. Berikut adalah posting saya yang lain yang menyelidiki berbagai kombinasi tempat membangun sintaks .