Joomla Chọn từ nhóm DB AND / OR

Jan 26 2021

Tôi không tìm thấy bất kỳ hướng dẫn nào về cách xử lý các truy vấn như vậy trong Joomla:

Tôi muốn chọn tất cả các mục từ db là:

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)

để nhận tất cả các mục đã được xuất bản và datenow nằm trong ngày bắt đầu / kết thúc xuất bản hoặc khi các giá trị bắt đầu / kết thúc đã đặt không được đặt.

Những gì tôi có cho đến nay là một truy vấn đơn giản:

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

Cho đến nay rất tốt nhưng cuối cùng nó tạo ra một truy vấn như vậy:

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 không đặt hoặc nhóm truy vấn khi tôi cần, đầu tiên là VÀ và sau đó mọi thứ khác là HOẶC.

Tôi chắc chắn rằng nó chỉ là một lỗ hổng kiến ​​thức / cú pháp chứ không phải là một lỗi - nhưng cách chính xác để viết một truy vấn phù hợp dựa trên nhu cầu của tôi là như thế nào?

PS: Bảng DB là từ một thành phần tùy chỉnh

Trả lời

2 mickmackusa Jan 27 2021 at 07:29

0000-00-00 00:00:00sẽ luôn ít hơn tem ngày giờ hiện tại, tôi hiểu các yêu cầu của bạn như:

published = 1
AND
publish_up <= now
AND
(
    publish_down = 0000-00-00 00:00:00
    OR
    publish_down > now
)
  • where()có giá trị keo mặc định là AND.
  • andWhere()có giá trị keo mặc định là OR.

Để dịch điều đó sang trình xây dựng truy vấn của Joomla, bạn sẽ viết:

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

Logic yêu cầu của bạn hoàn toàn phù hợp với keo mặc định của phương pháp, vì vậy không cần khai báo keo.

SQL được kết xuất:

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

Ghi chú:

  1. Chuỗi hay không chuỗi các cuộc gọi phương thức không ảnh hưởng đến cách tạo sql. Nói cách khác, bạn không nhận được hoặc mất bất kỳ dấu ngoặc nào từ việc tiếp tục hoặc phá vỡ một "chuỗi" các lệnh gọi phương thức.

  2. Tôi sẽ sử dụng CURRENT_TIMESTAMPtrừ khi của bạn $datekhông phải là những gì tôi nghĩ. Giống:

    $db->quoteName('publish_up') . ' <= CURRENT_TIMESTAMP',
    
  3. Đây là một bài đăng khác của tôi đi sâu vào các kết hợp khác nhau của cú pháp xây dựng ở đâu .