Получить общее количество продуктов по брендам с несколькими категориями с PHP и MySQL - PullRequest
0 голосов
/ 05 апреля 2020

У меня есть запрос: SELECT brand FROM products WHERE brand='".$brand."' AND category='".$id."'".$categories_list."

Идея состоит в том, чтобы получить общее количество продуктов в категории или по нескольким категориям по идентификатору категории или идентификаторам по номеру бренда.

Код как есть:

foreach ($product_brands as $brand) {
    $products_sql = mysqli_query($mysql_link, "SELECT brand FROM products WHERE brand='".$brand."' AND category='".$id."'".$categories_list."");
    $brand_total = @mysqli_num_rows($products_sql);
    array_push ($product_brands_count, $brand_total);
}

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

$categories_list добавляет OR category='".$categories_data['id']."' к запросу, если отображается несколько категорий.

Я пытался переместить brand='".$brand."' в запросе, но у меня это не сработало.

Вот некоторые из подсчетов, которые я получаю.

Отдельная категория: - это правильно

Brand 1 = 3 
Brand 2 = 5

Несколько категорий - это не

Brand 1 = 8
Brand 2 = 11

1 Ответ

2 голосов
/ 05 апреля 2020

Ваша основная проблема - это проблема логического приоритета. Вы генерируете предложение where, например:

WHERE brand = ? AND category = ? OR category = ?

Поскольку AND имеет более высокий приоритет, чем AND, это фактически означает:

WHERE (brand = ? AND category = ?) OR category = ?

Это принимает строки, чьи категории соответствуют параметр второй категории, независимо от их бренда.

Вам нужны круглые скобки, чтобы контролировать преимущество:

WHERE brand = ? AND (category = ? OR category = ?)

Это можно сократить с помощью IN:

WHERE brand = ? AND category IN (?, ?)

Но суть в том, что я не вижу смысла перебирать бренды в php, извлекать все строки и затем считать их. Ваша база данных может намного эффективнее управлять наборами строк с помощью запроса агрегации.

Что-то вроде этого должно быть близко к тому, что вам нужно:

select brand, count(*) no_products
from products
group by brand
where category in (?, ?)

Обратите внимание, что все вышеперечисленные запросы параметризованный (ie параметры не объединяются в строке запроса, а вместо этого передаются в запрос в execute время). Вы делаете хотите использовать эту технику, чтобы сделать ваш код более эффективным и предотвратить SQL внедрение.

...