Lọc bộ sưu tập sản phẩm theo thuộc tính khác trong Bộ sưu tập sản phẩm, ví dụ: 'attribX', mảng ('gt' => 'attrib-Y')


7

Khi sử dụng bộ sưu tập sản phẩm như vậy:

$_productCollection= Mage::getModel('catalog/product')->getCollection()
                    ->addAttributeToSelect('*')
                    ->addAttributeToFilter('special_price', array('neq'=>''));

Có thể sử dụng addAttributionToFilter trên một thuộc tính so với thuộc tính khác không? ví dụ: Tôi có thể lọc Special_price lớn hơn giá bằng thứ gì đó như

$_productCollection= Mage::getModel('catalog/product')->getCollection()
                    ->addAttributeToSelect('*')
                    ->addAttributeToFilter('special_price', array('gt'=>'price'));

Câu trả lời:


4

Tôi nghĩ rằng bạn có thể đạt được điều này bằng cách sử dụng addExpressionAttributeToSelect. Xem lớp Mage_Eav_Model_Entity_Collection_Abstractcho điều này. Bạn có thể thử một cái gì đó như thế này:

$_productCollection= Mage::getModel('catalog/product')->getCollection()
    ->addAttributeToSelect('*')
    ->addExpressionAttributeToSelect('difference', '(IF ({{special_price}} > {{price}} , 1, 0))', array('special_price', 'price'));

Điều này sẽ thêm một "cột" mới được đặt tên differencecho lựa chọn có giá trị 1 nếu giá đặc biệt lớn hơn giá. Bây giờ tất cả bạn phải làm là lọc theo cột đó.

$_productCollection->getSelect()->having('difference = ?', 1);

Giải pháp tốt, đơn giản, nhưng nếu bạn cần hiệu suất truy vấn tối ưu, tốt hơn hết là tránhHAVING
Fabian Schmengler

Tôi không nghĩ nó hoạt động khác
Marius

Giải pháp của tôi là ít đơn giản hơn, nhưng dường như làm việc.
Fabian Schmengler

1

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 differencetrong 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.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.