查询相关产品

时间:2010-07-15 11:48:39

标签: php mysql

我有产品的详细页面,我想添加“相关产品”的模块。

在db表“products”中,我为每个产品存储一个名为“tags”的值,例如“tag1,tag2,tag3,tag4”。

现在我需要构建一个查询,检索与此标记中至少有2个匹配的所有产品,不包括详细信息页面中显示的主要产品的ID。例如:

主要产品

  

产品名称| tag1,tag2,tag3,tag4

相关产品:

  

产品名称| tag1,tag3,tag5

     

产品名称| tag3,tag4,tag6,tag7

我不确定最好的方法是SQL ...也许是使用数组的PHP函数?

感谢。

2 个答案:

答案 0 :(得分:5)

将多值属性存储在单个字段中并不是一个好主意。理想情况下,您将拥有Products表,Tags表和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;
}

它有点粗糙并准备就绪,但它应该有效。此代码假定您有名为productNametags的列。

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。它会为您提供相关产品。与他们一起做你想做的事!

答案 1 :(得分:0)

其他人已经指出,这个,逗号,分隔,标记,列表并不是一个好主意。这是真的,我知道这很难。

如果您必须使用它,您可以使用表服务器来过滤您的结果集     WHERE标记LIKE'%searchtag%'

但是这个搜索术语会非常缓慢,并且会返回误报。 你最好创建一个product_tags表,每个产品的每个标签都有一行。