2016-12-05 15 views
1

Я хочу сортировать товары в категории по умолчанию фильтры (например, положение, цена ...) и по количеству. Продукты с количеством = 0 должны быть в конце списка.PrestaShop Сортировка нескольких полей в категории

По умолчанию запрос в category.php (https://github.com/PrestaShop/PrestaShop/blob/1.6.1.x/classes/Category.php#L688)

Я пытаюсь добавить количество к заказу, но результаты сортируются только по позиции

if ($random === true) { 
    $sql .= ' ORDER BY RAND(), stock.`quantity` DESC LIMIT '.(int)$random_number_products; 
} else { 
    $sql .= ' ORDER BY '.(!empty($order_by_prefix) ? $order_by_prefix.'.' : '').'`'.bqSQL($order_by).'` '.pSQL($order_way).', stock.`quantity` DESC 
    LIMIT '.(((int)$p - 1) * (int)$n).','.(int)$n; 
} 

Я пытаюсь изменить этот запрос путем добавления подзапрос для avaliable_stock, но результат тот же, сортируются только по позиции

$sql = 'SELECT p.*, product_shop.*, real_quantity.*'.(Combination::isFeatureActive() ? ', IFNULL(product_attribute_shop.id_product_attribute, 0) AS id_product_attribute, 
      product_attribute_shop.minimal_quantity AS product_attribute_minimal_quantity' : '').', pl.`description`, pl.`description_short`, pl.`available_now`, 
      pl.`available_later`, pl.`link_rewrite`, pl.`meta_description`, pl.`meta_keywords`, pl.`meta_title`, pl.`name`, image_shop.`id_image` id_image, 
      il.`legend` as legend, m.`name` AS manufacturer_name, cl.`name` AS category_default, 
      DATEDIFF(product_shop.`date_add`, DATE_SUB("'.date('Y-m-d').' 00:00:00", 
      INTERVAL '.(int)$nb_days_new_product.' DAY)) > 0 AS new, product_shop.price AS orderprice 
     FROM `'._DB_PREFIX_.'category_product` cp 
     LEFT JOIN `'._DB_PREFIX_.'product` p 
      ON p.`id_product` = cp.`id_product` 
     '.Shop::addSqlAssociation('product', 'p'). 
     (Combination::isFeatureActive() ? ' LEFT JOIN `'._DB_PREFIX_.'product_attribute_shop` product_attribute_shop 
     ON (p.`id_product` = product_attribute_shop.`id_product` AND product_attribute_shop.`default_on` = 1 AND product_attribute_shop.id_shop='.(int)$context->shop->id.')':'').' 
     LEFT JOIN `'._DB_PREFIX_.'category_lang` cl 
      ON (product_shop.`id_category_default` = cl.`id_category` 
      AND cl.`id_lang` = '.(int)$id_lang.Shop::addSqlRestrictionOnLang('cl').') 
     LEFT JOIN `'._DB_PREFIX_.'product_lang` pl 
      ON (p.`id_product` = pl.`id_product` 
      AND pl.`id_lang` = '.(int)$id_lang.Shop::addSqlRestrictionOnLang('pl').') 
     LEFT JOIN `'._DB_PREFIX_.'image_shop` image_shop 
      ON (image_shop.`id_product` = p.`id_product` AND image_shop.cover=1 AND image_shop.id_shop='.(int)$context->shop->id.') 
     LEFT JOIN `'._DB_PREFIX_.'image_lang` il 
      ON (image_shop.`id_image` = il.`id_image` 
      AND il.`id_lang` = '.(int)$id_lang.') 
     LEFT JOIN `'._DB_PREFIX_.'manufacturer` m 
      ON m.`id_manufacturer` = p.`id_manufacturer` 
     LEFT JOIN (SELECT * FROM `'._DB_PREFIX_.'stock_available` ORDER BY `quantity` DESC) AS real_quantity 
      ON (real_quantity.id_product = p.id_product AND real_quantity.id_product_attribute = 0 AND real_quantity.id_shop = '.(int)$context->shop->id.') 
     WHERE product_shop.`id_shop` = '.(int)$context->shop->id.' 
      AND cp.`id_category` = '.(int)$this->id 
      .($active ? ' AND product_shop.`active` = 1' : '') 
      .($front ? ' AND product_shop.`visibility` IN ("both", "catalog")' : '') 
      .($id_supplier ? ' AND p.id_supplier = '.(int)$id_supplier : ''); 

if ($random === true) { 
    $sql .= ' ORDER BY RAND(), real_quantity.`quantity` DESC LIMIT '.(int)$random_number_products; 
} else { 
    $sql .= ' ORDER BY '.(!empty($order_by_prefix) ? $order_by_prefix.'.' : '').'`'.bqSQL($order_by).'` '.pSQL($order_way).', real_quantity.`quantity` DESC 
    LIMIT '.(((int)$p - 1) * (int)$n).','.(int)$n; 
} 

Может кто-нибудь помочь/советовать мне с этой проблемой?

ответ

1

ORDER BY предложение в SQL работает следующим образом:

ORDER BY column1, column2 /*order results by column1, if 2 rows has the same column1 value then compare by column2*/ 

Это означает, что в вашем предложении MySQL второй столбец никогда не будет принимать во внимание, так как значения первого столбца (позиции) всегда различны.

Тогда, если вы хотите, чтобы всегда упорядочить по количеству вы должны сделать что-то вроде этого (asumming что real_quantity уже имеет правильное значение quantyti):

if ($random === true) { 
    $sql .= ' ORDER stock.`quantity` DESC LIMIT '.(int)$random_number_products; 
} else { 
    $sql .= ' ORDER BY stock.`quantity` DESC 
    LIMIT '.(((int)$p - 1) * (int)$n).','.(int)$n; 
} 

Если продукт с количеством 0 должно появиться в конце список, то порядок по умолчанию не будет работать для вас, как я вам объясняю раньше. Если вы хотите сохранить заказ по умолчанию, но покажите продукт без запаса в конце, вы должны сделать 2 отдельных оператора SQL: 1 для продуктов со складом> 0 (с использованием условия WHERE), сохраняя заказ по умолчанию, а другой - без продуктов. Затем слейте результаты.

Удачи.

+0

Обязательный заказ должен быть оставлен, а товары с нулевым количеством в конце списка отображаются с разбивкой по страницам (LIMIT) – esik

+1

Если в конце списка появляется продукт с количеством 0, то для вас не будет установлен заказ по умолчанию как я объясняю вам раньше. Если вы хотите сохранить заказ по умолчанию, но покажите продукт без запаса в конце, вы должны сделать два отдельных оператора SQL: 1 для продуктов с запасом> 0 (используя условие WHERE), сохраняя порядок по умолчанию, а другой - без продуктов. Затем слейте результаты. – PixelWeb

+0

Я нашел лучший способ, например 'ORDER BY stock.quantity> 0 DESC, имя pl.name ASC' сначала по количеству, а затем по имени – esik