2010-07-15 3 views
3

У меня есть подробная страница для продуктов, и я хочу добавить модуль «родственных продуктов».Запрос на сопутствующие товары

В таблице db «продукты» я храню значение, называемое «тегами» для каждого продукта, что-то вроде «tag1, tag2, tag3, tag4».

Теперь мне нужно создать запрос, который извлекает все продукты, которые соответствуют по меньшей мере 2 из этих тегов, за исключением идентификатора основного продукта, отображаемого на странице подробностей. Например:

Основной продукт

Наименование | tag1, tag2, tag3, Вкладка4

Связанные продукты:

Наименование | tag1, tag3, tag5

Наименование продукта | tag3, tag4, tag6, tag7

Я не уверен, что лучший способ сделать это SQL ... возможно, функция PHP с использованием массива?

Спасибо.

+1

Есть ли способ нормализовать столбец тегов?т.е. создать 2 новые таблицы: 'tag' и' product_tag' –

+0

@Dennis Haarbrink: да, я мог бы иметь новые таблицы ... – Luciano

ответ

5

Не стоит хранить многозначный атрибут в одном поле. В идеале у вас будет таблица Products, таблица тегов и таблица ProductTags.

Однако, вы можете выбрать Тэги для Продукта и использовать explode(), чтобы получить массив тегов. Для каждого другого продукта выполните то же самое и используйте array_intersect, чтобы получить массив общих элементов. Затем с помощью count() > 1, чтобы определить, является ли это связано

Итак:

function getRelatedProducts($productName) 
{ 
    $productResults = mysql_query("SELECT * FROM products WHERE productName = '$productName' LIMIT 0,1"); 

    $relatedProducts = array(); 

    if(mysql_num_rows($productResults) == 1) 
    { 
     $product = mysql_fetch_array($productResults); 
     $tags = explode(",",$product['tags']); 

     $otherProducts = mysql_query("SELECT * FROM products WHERE productName != '$productName'"); 

     while($otherProduct = mysql_fetch_array($otherProducts)) 
     { 
      $otherTags = explode(",",$otherProduct['tags']); 
      $overlap = array_intersect($tags,$otherTags); 
      if(count($overlap > 1)) $relatedProducts[] = $otherProduct; 
     } 
    } 

    return $relatedProducts; 
} 

Это немного грубый и готов, но он должен работать. Этот код предполагает, что у вас есть столбцы с именем productName и tags.

PHP:array_intersect - Manual

Если вы идете вперед с таблицей product_tags, вы можете использовать следующий код, чтобы найти соответствующие продукты:

function getRelatedProducts($productId) 
{ 
    $sql = "SELECT p.*,COUNT(*) AS matchedTags FROM products p 
      INNER JOIN product_tags pt ON pt.product_id = p.id 
      WHERE pt.tag_id IN (SELECT tag_id FROM product_tags WHERE product_id = $product_id) 
      GROUP BY p.id 
      HAVING COUNT(*) > 1"; 

    $results = mysql_query($sql); 

    $relatedProducts = array(); 

    while($result = mysql_fetch_array($results)) 
    { 
     $relatedProducts[] = $result; 
    } 

    return $relatedProducts; 
} 

Важной частью является SQL в начале функции. Он предоставит вам соответствующие продукты. Сделайте с ними то, что будете!

+0

Thanx Brendan! В любом случае, если вы предложите мне иметь таблицу тегов и таблицу product_tags, я буду двигаться таким образом. Но тогда, как я могу запросить db? Я полагаю, что таблица тегов должна иметь: id, tag_name. И product_tags: id, product_id, tag_id – Luciano

+0

@Luciano Это точно. Вы можете установить уникальный индекс между product_id и tag_id в таблице product_tags, чтобы предотвратить дублирование тегов на продукте. –

+0

Удивительный! Еще раз спасибо за ответы и примеры, было действительно полезно! – Luciano

0

Другие указали, что это, запятая, отделенная, бирка, список не такая хорошая идея. Это правда, и я знаю, что трудно.

Если вы должны использовать его, вы можете использовать сервер таблицы для фильтрации результирующего набора с WHERE тег LIKE «% searchtag%»

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

+0

вы имеете в виду [этот пример] (http://leonpanjtar.eu/web-design-blog/mysql-related-products-query/) с 'ProductTable' и' ProductTagsTable' и еще один 'ProductsXTagsTable', чтобы поддерживать соединение между продуктов и таблиц, или вы можете отредактировать сообщение и показать пример с запросом на поиск по быстродействующим продуктам? – stom

Смежные вопросы