我有产品的详细页面,我想添加“相关产品”的模块。
在db表“products”中,我为每个产品存储一个名为“tags”的值,例如“tag1,tag2,tag3,tag4”。
现在我需要构建一个查询,检索与此标记中至少有2个匹配的所有产品,不包括详细信息页面中显示的主要产品的ID。例如:
主要产品
产品名称| tag1,tag2,tag3,tag4
相关产品:
产品名称| tag1,tag3,tag5
产品名称| tag3,tag4,tag6,tag7
我不确定最好的方法是SQL ...也许是使用数组的PHP函数?
感谢。
答案 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;
}
它有点粗糙并准备就绪,但它应该有效。此代码假定您有名为productName
和tags
的列。
如果您继续使用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表,每个产品的每个标签都有一行。