Joomla เลือกจากฐานข้อมูลและ / หรือการจัดกลุ่ม

Jan 26 2021

ฉันไม่พบคำแนะนำใด ๆ เกี่ยวกับวิธีจัดการกับคำถามดังกล่าวใน Joomla:

ฉันต้องการเลือกรายการทั้งหมดจากฐานข้อมูลซึ่ง ได้แก่ :

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)

เพื่อรับรายการทั้งหมดที่เผยแพร่และวันที่อยู่ภายในวันที่เริ่มต้น / สิ้นสุดการเผยแพร่หรือเมื่อไม่ได้ตั้งค่าเริ่มต้น / สิ้นสุดที่กำหนดไว้

สิ่งที่ฉันมีคือแบบสอบถามง่ายๆ:

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

จนถึงตอนนี้ดีมาก แต่ในที่สุดมันก็สร้างแบบสอบถามดังนี้:

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 ไม่ได้ตั้งค่าหรือจัดกลุ่มคิวรีตามที่ฉันต้องการอย่างแรกคือ AND จากนั้นทุกอย่างก็คือ OR

ฉันแน่ใจว่ามันเป็นเพียงช่องว่างความรู้ / ไวยากรณ์แทนที่จะเป็นจุดบกพร่อง - แต่วิธีที่ถูกต้องในการเขียนแบบสอบถามที่เหมาะสมตามความต้องการของฉันเป็นอย่างไร

PS: ตาราง DB มาจากส่วนประกอบที่กำหนดเอง

คำตอบ

2 mickmackusa Jan 27 2021 at 07:29

เนื่องจาก0000-00-00 00:00:00จะน้อยกว่าการประทับวันที่และเวลาปัจจุบันเสมอฉันเข้าใจความต้องการของคุณดังนี้:

published = 1
AND
publish_up <= now
AND
(
    publish_down = 0000-00-00 00:00:00
    OR
    publish_down > now
)
  • where()มีค่ากาวเริ่มต้นเป็นAND.
  • andWhere()มีค่ากาวเริ่มต้นเป็นOR.

ในการแปลสิ่งนั้นเป็น Querybuilder ของ Joomla คุณจะต้องเขียน:

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

ตรรกะที่คุณต้องการสอดคล้องกับกาวเริ่มต้นของวิธีการอย่างสมบูรณ์แบบดังนั้นจึงไม่จำเป็นต้องมีการประกาศกาว

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

หมายเหตุ:

  1. การเชื่อมโยงหรือไม่ผูกมัดการเรียกเมธอดไม่ส่งผลกระทบต่อวิธีการสร้าง sql กล่าวอีกนัยหนึ่งคือคุณจะไม่ได้รับหรือสูญเสียวงเล็บใด ๆ จากการดำเนินการต่อหรือทำลาย "ห่วงโซ่" ของการเรียกเมธอด

  2. ฉันจะใช้CURRENT_TIMESTAMPเว้นแต่คุณ$dateจะไม่ใช่อย่างที่ฉันคิด ชอบ:

    $db->quoteName('publish_up') . ' <= CURRENT_TIMESTAMP',
    
  3. นี่คืออีกหนึ่งของการโพสต์ของฉันที่ขุดคุ้ยแตกต่างกันของการที่สร้างไวยากรณ์