在搜索中需要帮助[关闭]
Posted
技术标签:
【中文标题】在搜索中需要帮助[关闭]【英文标题】:need help in search [closed] 【发布时间】:2012-08-25 03:01:52 【问题描述】:根据我的系统,我需要根据类别和子类别搜索品牌。
这样的品牌表
id brandname categoryid subcategoryid
1 xys 1,2,3 1,5,6
现在当我搜索时我选择类别然后根据类别所有子类别现在我选择子类别现在需要显示基于该类别和子类别的所有品牌。 我的品牌表是这样的,因为同一个品牌有多个类别和子类别。请帮我解决这个问题
【问题讨论】:
糟糕的数据库设计。使用关系而不是 CSV 数据,您可以通过连接解决问题。 @suman 停止恢复为未设置样式。 @ckruse 我需要为多个类别添加品牌,请您给我一些建议 停止在数据库中存储逗号分隔的值,而不是使用关系 plz 尝试重新思考您存储类别和子类别的方式;除非您有很好的理由不更改它,否则这将是您所要求的最简单的解决方案。 【参考方案1】:鉴于您的数据库设计,您可以这样做:
SELECT * FROM mytable WHERE
FIND_IN_SET('5', categoryid) > 0 AND FIND_IN_SET('3', subcategoryid) > 0;
这将找到类别 5 和子类别 3 中的所有项目。
SELECT * FROM mytable WHERE
FIND_IN_SET('5', categoryid) > 0 AND (
FIND_IN_SET('3', subcategoryid) > 0
OR
FIND_IN_SET('9', subcategoryid) > 0
);
上面将找到类别 5、子类别 3 和 9 中的项目。当然,您也可以通过使用 AND
而不是 OR
来限制 both 类别中的项目。
但这一切都是不必要的昂贵。如果有一个品牌名称表,以及其他用于类别和子类别 ID 和链接的表,您会做得更好,如下所示:
// This is an article. Many-to-one relation with brands.
CREATE TABLE articles
(
id integer primary key not null auto_increment,
name varchar(...),
brand_id integer,
//, other data
);
CREATE TABLE brands
(
id integer primary key not null auto_increment,
name varchar(...)
//, other data
);
// Categories. Many-to-Many relationship with articles.
CREATE TABLE categories
(
id integer primary key not null auto_increment,
name varchar(...)
//, other data
);
// Subcategories. These are independent from categories, which
// may be right or wrong, depending. Being independent, we do not
// store here parent_category_id.
CREATE TABLE subcategories
(
id integer primary key not null auto_increment,
name varchar(...)
//, other data
);
// Many to many relationship between articles and categories
CREATE TABLE mtm_article_in_category
(
article_id integer not null,
category_id integer not null
);
CREATE TABLE mtm_article_in_subcategory
(
article_id integer not null,
subcategory_id integer not null
);
// Add article 5 to categories 25, 37 and 119:
INSERT IGNORE INTO mtm_article_in_category VALUES ( 5, 25 ), ( 5, 37 ), ( 5, 119 );
// Remove article 18 from subcategory 92
DELETE FROM mtm_article_in_category WHERE article_id = 18 AND subcategory_id = 92;
通过这种方式,您可以运行更快的查询,并且不会出现无法将文章分配到“这么多”类别(例如 50 个)等问题;如果您想将一篇文章从一个类别移到另一个类别,也不会让人头疼,而您目前的设计几乎是不可能的。
起初我的搜索是这样的,我选择了所有子类别 根据类别来。然后当我选择子类别时,所有品牌 基于该类别和子类别来。现在我添加一个品牌名称 一次有多个类别和多个子类别。
我不得不说,“天哪”。为了能够“选择所有子类别”/now/,您必须对其进行转换
category subcategory
4,5 1,7,9,19
5 7,9,11
在 5 1 5 7 5 9 5 19 5 7 5 9 5 11
然后运行DISTINCT
,最后使用基于FIND_IN_SET
的INNER JOIN
子类别。
第一步(“分解”一个 CSV 行)可以这样完成:http://www.marcogoncalves.com/2011/03/mysql-split-column-string-into-rows/ ... 正如您所见,这几乎是微不足道的。
我希望您目前正在 php 中进行拆分。
这样做之后,INNER JOIN
非常昂贵。
我们正在把好钱扔在坏钱之后。您当前的数据库设计不允许轻松地做您想做的事。最简单的方法是:
// My search like this at first i chose category the all the subcategory
// come based on category.
$query = "SELECT subcategoryid FROM mytable WHERE FIND_IN_SET(:mycategory, categoryid) > 0;";
// and run the query.
$subcategories = array();
while($tuple = sql_fetch_tuple($exec))
// Explode "1,2,3" into array 1, 2, 3. Merge into subcategories removing
// duplicates. Rinse. Repeat.
$subcategories = array_unique(array_merge($subcategories, explode(',', $tuple['subcategoryid'])));
sql_free($exec);
// Now we have an array of subcategories.
// Then when i chose subcategory all the brand
// based on that category and subcategory come.
$subcat_query = array();
foreach($subcategories as $subcategory)
$subcat_query[] = "FIND_IN_SET('$subcategory', subcategoryid)";
$subcat_query_sql = implode(' OR ', $subcat_query);
$query = "SELECT DISTINCT brand FROM mytable WHERE FIND_IN_SET(:cat, categoryid) AND ( $subcat_query_sql );";
// And here we get all brands. It is wise to save $subcat_query_sql in _SESSION.
// Next search will be:
// >Now i add one brand name
// > one time with multiple category and multiple subcategory.
// Note that you've subtly moved the target once more, now the 'category' has become "multiple".
$brands_arr[] = array();
foreach($brands as $brand)
$brands_arr[] = "'" . sql_escape($brand) . "'";
$brands_sql = implode(',', $brands_arr);
// The cost of this $query is estimated as a significant percentage of U.S. gross internal product, so it ought to be cleared with the FED.
$query = "SELECT * FROM mytable WHERE brand IN ($brands_sql) AND FIND_IN_SET(:cat, categoryid) AND ( $subcat_query_sql );";
上述查询也有可能什么都不返回。假设您查找子类别 5 和类别 12。根据您的要求,获取“所有子类别”和“所有类别”可能还会返回品牌 6 和子类别 9。然后这两行就出来了,
Marlboro 5 12
Lucky 6 9
并且用户选择“Marlboro 6 12”。他不会得到任何东西 - 没有行会匹配该查询。
恐怕用户界面和工作流程/用例也需要研究。
【讨论】:
感谢您的回答主要问题是我需要根据类别和子类别自动生成所有品牌名称,我还开发类别和子类别表。但是如果我没有类别和子类别的外键,我如何根据类别和子类别生成品牌名称你能帮我解决这个问题吗? “根据类别和子类别自动生成品牌名称”是什么意思?你说你想搜索,所以这就是我告诉你的方法。无论如何都会尝试编辑答案。 我的搜索一开始是这样的具有多个类别和多个子类别。 编辑答案。不知何故,我想在之后添加长者标志。以上是关于在搜索中需要帮助[关闭]的主要内容,如果未能解决你的问题,请参考以下文章