Перейти к содержанию
Официальный форум поддержки Simpla

Категории в Компании, или логика задом наперед


Перейти к решению Решено Noxter,

Рекомендуемые сообщения

Привет ребята, возникла второй раз уже необходимость сделать так,
чтобы человек зайдя в бренд, тем самым заполнив переменную $brand
мог увидеть какие категории содержит сие бренд.
 

Например: http://felicita63.ru/brands/kuppersbusch

Решил поделиться решением, возможно и не самым красивым в
плане производительности, хотя ухудшения на практике не заметил.
Решение работало в 2.24, в 2.3.5 тоже нормалек.


Первым делом добавим в низовья файла /api/Products.php

//функция позволяет узнать все категории, в которых есть товары определенной компании
    public function brands_category($bandd_id) 
        {
        $this->db->query("
            SELECT c.id, c.name, c.url, b.url AS brand
            FROM s_categories AS c
            LEFT JOIN s_products_categories AS pc
            ON pc.category_id = c.id
            LEFT JOIN s_products AS p
            ON p.id = pc.product_id
            LEFT JOIN s_brands AS b
            ON b.id = p.brand_id
            WHERE b.id=? 
            AND c.visible = 1
            GROUP BY c.id
            ORDER BY c.name ASC
        ", $bandd_id); 
        $brand_categories = $this->db->results();
        return $brand_categories;
        }    

// Спасибо за быстрый код пользователю Noxter

 

Думаю всем все ясно чего тут и куда, научились получать необходимую информацию,

опозжее сия момента произведите следующую манипуляцию с файлом /view/ProductsView.php

Примерно с 32 строки переделываем функцию в вот такую:

// Если задан бренд, выберем его из базы
if (!empty($brand_url))
{	
$brand = $this->brands->get_brand((string)$brand_url);
	if (empty($brand))
		return false;
	
	$this->design->assign('brand', $brand);
	$filter['brand_id'] = $brand->id;
	
	//Получаем категории бренда и передаем их в шаблон
	$brand_cat= $this->products->brands_category($brand->id);
	$this->design->assign('brand_cat', $brand_cat);
}

 

Собственно почти все, почти готово, имеем нужную информацию, можно пользоваться в шаблонах:

{if ($brand)}

<div class="sort companysort">
	<h2 style="margin-bottom: 10px;">Товары компании представлены в категориях</h2>
	<a href="brands/{$brand->url}{if !($smarty.server.REQUEST_URI|strstr:'brands')}&show=1{/if}"><div {if ($smarty.server.REQUEST_URI|strstr:'brands')}class="selected"{/if}>Все категории</div></a>
	{foreach $brand_cat as $bc}
		<a href="catalog/{$bc->url}/{$brand->url}"><div {if $category->url == $bc->url}class="selected"{/if}>{$bc->name}</div></a>
	{/foreach}
</div>

{/if}
Или иными, более изощренными методами, для коих у вас нынче есть инструментарий.

 

Надеюсь будет полезно, пользуйтесь на здоровье(счастье).

 

Если не поскупитесь за полезность - +7 937 204-69-07.

Ссылка на сообщение
Поделиться на другие сайты

Я делал такое только не таким топорным методом.

Напомните на днях напишу урок.

 

Ну вы то вон какой козырь острый, я и написал, что метод не из прекрасных. Заранее спасибо за прекрасный)

 

x_c3c194ef.jpg

Ссылка на сообщение
Поделиться на другие сайты

Метод не только "топорный", но просто таки вредительский в плане создания тормозов.

Если данных в магазине немного, но, может, и незаметно.

А с возрастанием количества товаров у бренда нагрузка будет возрастать в арифметической прогрессии.

Первый пост - характерный пример того, как НЕЛЬЗЯ делать.

 

А уж намекать на деньги за такую откровенную халтуру - совсем нехорошо...

На месте владельца серьезного магазина можно смело отдать 3000 руб, только чтобы такое НЕ устанавливать. Ибо в случае установки убытки будут куда больше...

 

Если Вы в профиле позиционируете себя как программист, то уж поработайте по-настоящему и поправьте свою функцию. Все, что она делает жутко затратными методами, можно выполнить чуть ли не одним-единственным запросом...

Привет товарисч, я и написал, что все бесплатно, давайте вы сделаете все прекрасненько.

При 1800 товарах ничего не изменилось со временем построения страницы) 

Ссылка на сообщение
Поделиться на другие сайты

 

Примерно так:



    //функция позволяет узнать все категории, в которых есть товары определенной компании
    public function brands_category($brand_id)
    {
    $this->db->query("SELECT DISTINCT c.id, c.name, c.url FROM s_products p, s_products_categories pc, s_categories c WHERE pc.product_id = p.id AND pc.category_id = c.id AND p.brand_id = ?", $brand_id);
    $brand_categories = $this->db->results();
    return $brand_categories;
    }	

 

Я считаю, что какой то тут не совсем правильный запрос получается... 

 

Как вариант:

"SELECT c.id, c.name, c.url FROM s_products AS p LEFT JOIN s_products_categories AS pc ON (pc.product_id=p.id) LEFT JOIN s_categories AS c ON (c.id=pc.category_id) WHERE p.brand_id = ? GROUP BY c.id"

Думаю выполнится быстрее

Ссылка на сообщение
Поделиться на другие сайты

Я считаю, что какой то тут не совсем правильный запрос получается... 

 

Как вариант:

"SELECT c.id, c.name, c.url FROM s_products AS p LEFT JOIN s_products_categories AS pc ON (pc.product_id=p.id) LEFT JOIN s_categories AS c ON (c.id=pc.category_id) WHERE p.brand_id = ? GROUP BY c.id"

Думаю выполнится быстрее

Я не знаю почему Вы считаете что вариант корса не правильный, но у меня вернуло как раз то что нужно для вывода категорий а именно название, ссылку и ее айди.

Ссылка на сообщение
Поделиться на другие сайты

Я не говорил что результаты будут не правельным... Дело в оптимизации.

Запрос kors сгружает все строки с таблиц s_products p, s_products_categories pc, s_categories.

Затем начинает сравнение pc.product_id = p.id AND pc.category_id = c.id AND p.brand_id = ?

А после отсеивает повторы - DISTINCT

 

Тот запрос что я дал - быстрее. Он должен пройти по уже проставленным индексам и проверить только на совпадение с p.brand_id 

Ссылка на сообщение
Поделиться на другие сайты

Я не говорил что результаты будут не правельным... Дело в оптимизации.

Запрос kors сгружает все строки с таблиц s_products p, s_products_categories pc, s_categories.

Затем начинает сравнение pc.product_id = p.id AND pc.category_id = c.id AND p.brand_id = ?

А после отсеивает повторы - DISTINCT

 

Тот запрос что я дал - быстрее. Он должен пройти по уже проставленным индексам и проверить только на совпадение с p.brand_id 

Ваш запрос занял 0.0018 сек. в то время как запрос корса занял 0.0011 сек., проверял в phpmyadmin со стандартной базой товаров симплы.

Ссылка на сообщение
Поделиться на другие сайты
  • Решение

Мой запрос занял 0.0007 сек.  :) выглядит громоздко но выполняется быстрее представленных вариантов

 

 

SELECT c.id, c.name, c.url, b.url AS brand
FROM s_categories AS c
LEFT JOIN s_products_categories AS pc
ON pc.category_id = c.id
LEFT JOIN s_products AS p
ON p.id = pc.product_id
LEFT JOIN s_brands AS b
ON b.id = p.brand_id
WHERE b.id=3 
AND c.visible = 1
GROUP BY c.id
ORDER BY c.name ASC
Ссылка на сообщение
Поделиться на другие сайты

Noxter Ну этого никак не может быть. Попробуйте через profiler. http://habrahabr.ru/post/70435/



Ну малые базы это не точно... Нужно пробовать на больших БД. Там сразу должно быть видно разницу

Ссылка на сообщение
Поделиться на другие сайты

 

Мой запрос занял 0.0007 сек.  :) выглядит громоздко но выполняется быстрее представленных вариантов

 

 

SELECT c.id, c.name, c.url, b.url AS brand
FROM s_categories AS c
LEFT JOIN s_products_categories AS pc
ON pc.category_id = c.id
LEFT JOIN s_products AS p
ON p.id = pc.product_id
LEFT JOIN s_brands AS b
ON b.id = p.brand_id
WHERE b.id=3 
AND c.visible = 1
GROUP BY c.id
ORDER BY c.name ASC

 

Ребята, красота, блеск, шик.

Вот этот вариант действительно быстрее всех, мой самый по бичу.

 

Ваши различаются очень мало, но этот стабильно быстрее строит конечную страничку.

 

Закину этот вариант в инструкцию?

Про оплату уберу.

Ссылка на сообщение
Поделиться на другие сайты

Если заменить LEFT JOIN на INNER JOIN, то запрос должен стать еще легче.

 

LEFT JOIN s_brands AS b - также можно удалить для облегчения

Ссылка на сообщение
Поделиться на другие сайты

Noxter Ну этого никак не может быть. Попробуйте через profiler. http://habrahabr.ru/post/70435/

Ну малые базы это не точно... Нужно пробовать на больших БД. Там сразу должно быть видно разницу

 

Чего не может быть? Если Вы о скорости, то прочтите мое сообщение еще раз в котором я четко написал:

Ваш запрос занял 0.0018 сек. в то время как запрос корса занял 0.0011 сек., проверял в phpmyadmin со стандартной базой товаров симплы.

 

Вы для начала протестируйте все 3 запроса в phpmyadmin как это сделал я, а уж потом спорьте.

Ссылка на сообщение
Поделиться на другие сайты

Я ж и протестировал! 1-корс 2-мой 3-ваш

И выложил скрин теста. Где сам себвер БД сказал что и как выполняется..

phpmyadmin в этом деле - не точный. Поскольку он возвращает результат за сколько выполнялось все. От вызова функции до получения результата. А я выложил прямые результаты с самого сервера БД

 

Если заменить LEFT JOIN на INNER JOIN, то запрос должен стать еще легче.

 

LEFT JOIN s_brands AS b - также можно удалить для облегчения

На счет INNER - согласен. Возможно даже лучше будет...
Ссылка на сообщение
Поделиться на другие сайты
  • 1 месяц спустя...

Полезно иной раз полистать и эту ветку форума. Полезная фича, взял на заметку для своего любимого магазинчика.

Ссылка на сообщение
Поделиться на другие сайты

Запрос для тех, кому нужно сделать вывод количества товаров бренда в категории:

SELECT c.id, c.name, c.url, b.url AS brand, count(p.id) as `products`
FROM s_categories AS c
INNER JOIN s_products_categories AS pc
ON pc.category_id = c.id
INNER JOIN s_products AS p
ON p.id = pc.product_id
INNER JOIN s_brands AS b
ON b.id = p.brand_id
WHERE b.id=3 
AND c.visible = 1
GROUP BY c.id
ORDER BY c.name ASC

Результат находится в ячейке products

 

PS: доработанный запрос от Noxter

Ссылка на сообщение
Поделиться на другие сайты
  • 1 год спустя...

Вставил код в /api/Products.php

 

на локальном сервере выдает ошибку

 

Parse error: syntax error, unexpected T_PUBLIC in Z:\home\localhost\www\site\api\Products.php on line 549

Изменено пользователем crab
Ссылка на сообщение
Поделиться на другие сайты

Видимо, вставил код не тот. Или не в то место вставил.

Для Вас написано сообщение об ошибке, расшифровано так, что понятнее уже некуда.

Можно предположить, что вставили в самый конец, а надо перед финальной скобкой "}"...

Ссылка на сообщение
Поделиться на другие сайты

Видимо, вставил код не тот. Или не в то место вставил.

Для Вас написано сообщение об ошибке, расшифровано так, что понятнее уже некуда.

Можно предположить, что вставили в самый конец, а надо перед финальной скобкой "}"...

Так и есть, вставил в самый конец, сейчас работает )

Ссылка на сообщение
Поделиться на другие сайты
  • 2 года спустя...

Всем доброго времени суток! Так был рад что нашёл способ осуществить эту идею (Огромная благодарность
PS-SIMPLA за помощь и уделённое время), но только что обломался немного...  :( 
Сделал в точности как описано в первом посте, но бренды не выводятся в шаблоне. 
С первым и вторым шагом косяки с моей стороны исключены, сомневаюсь касательно третего шага (добавления в шаблон). Уже как только не крутил этот кусок кода, пытался в тупую в индексный файл дефолтного шаблона прилепить, но полнейший ноль. Может подскажете в чём может быть трабл?
 

Изменено пользователем SimplaUser
Ссылка на сообщение
Поделиться на другие сайты

//функция позволяет узнать все категории, в которых есть товары определенной компании

public function brands_category($bandd_id)

{

$this->db->query("

SELECT c.id, c.name, c.url, b.url AS brand

FROM s_categories AS c

LEFT JOIN s_products_categories AS pc

ON pc.category_id = c.id

LEFT JOIN s_products AS p

ON p.id = pc.product_id

LEFT JOIN s_brands AS b

ON b.id = p.brand_id

WHERE b.id=?

AND c.visible = 1

GROUP BY c.id

ORDER BY c.name ASC

", $bandd_id);

$brand_categories = $this->db->results();

return $brand_categories;

}

 

// Спасибо за быстрый код пользователю Noxter

Это ведь не ошибки? Уже и их пытался исправлять. :lol:  :unsure:

Изменено пользователем SimplaUser
Ссылка на сообщение
Поделиться на другие сайты

С первым и вторым шагом косяки с моей стороны исключены, сомневаюсь касательно третего шага (добавления в шаблон). Уже как только не крутил этот кусок кода, пытался в тупую в индексный файл дефолтного шаблона прилепить, но полнейший ноль.

 

По моим наблюдениям, в подобных ситуациях в 90% случаев ошибка оказывается очень далеко от того места, где ее настойчиво ишут...

 

Может подскажете в чём может быть трабл?

 

Еше могут быть  сотни мест и сотни причин. Хотите все предположения - читайте книги по PHP, Smarty, WEB-строительству. В интернете Вам  материала для чтения на тысячу лет точно хватит...

 

Обычно, если хотят решить вопрос, дают ТОЧНЫЕ сведения о своих действиях, а не размытыми ничего не значащими фразами типа "как только не крутил"...

Ссылка на сообщение
Поделиться на другие сайты
  • 3 недели спустя...

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

Загрузка...
×
×
  • Создать...