Bạn có thể sử dụng Zend_Db_Expr
để sử dụng SQL thô thay vì giá trị. Nhưng với các bộ sưu tập sản phẩm, bạn phải cẩn thận vì truy vấn sẽ khác nếu chỉ số sản phẩm phẳng được bật
EAV (tắt chỉ mục phẳng hoặc khu vực quản trị)
Ở đây chúng ta cần thêm bộ lọc cho thuộc tính thứ hai vì các thuộc tính được chọn sẽ được tải trong truy vấn thứ hai và bạn không có quyền truy cập vào thuộc tính khác. Chọn một cái gì đó luôn luôn đúng, tôi đã đi 'không đáng kể'. Bảng thuộc tính được nối có thể được tham chiếu với mã thuộc tính "at_" +:
$_productCollection
->addAttributeToFilter('price', ['notnull' => true])
->addAttributeToFilter(
'special_price',
['lt' => new Zend_Db_Expr('at_price.value')]
);
Sử dụng chỉ số phẳng
Với chỉ mục phẳng, bạn có thể truy cập trực tiếp bất kỳ thuộc tính nào được bao gồm trong chỉ mục phẳng (nghĩa là "Được sử dụng trong danh sách sản phẩm"):
$_productCollection->addAttributeToFilter(
'special_price',
['lt' => new Zend_Db_Expr('price')]
);
Giải pháp phổ quát
Sử dụng addExpressionAttributeToSelect()
như được đề xuất bởi @Marius, chúng tôi có thể đảm bảo rằng tất cả các thuộc tính được sử dụng trong biểu thức đều khả dụng, mà không phải thêm bộ lọc giả (cả hai chỉ là cách giải quyết nhưng hoạt động tốt như nhau). Sau đó, chúng ta chỉ cần sử dụng một biểu thức khác nhau, tùy thuộc vào isEnabledFlat()
:
$priceExpression = $_productCollection()->isEnabledFlat()
? new Zend_Db_Expr('price')
: new Zend_Db_Expr('at_price.value');
$_productCollection
->addExpressionAttributeToSelect('difference', '(IF ({{special_price}} > {{price}} , 1, 0))', array('special_price', 'price'));
->addAttributeToFilter(
'special_price',
['lt' => $priceExpression]
);
Lưu ý rằng chúng tôi không thực sự sử dụng difference
trong bộ lọc, vì WHERE
được thực thi trước khi giá trị được tính toán. Nhưng điều này cũng có nghĩa, MySQL có thể tối ưu hóa truy vấn tốt hơn so với HAVING
, được thực hiện sau cùng.
HAVING