根据我的系统,我需要根据类别和子类别搜索品牌。
像这样的品牌表
id brandname categoryid subcategoryid
1 xys 1,2,3 1,5,6
现在,当我搜索时,我选择类别然后根据类别所有子类别现在我选择子类别现在需要显示基于该类别和子类别的所有品牌。我的品牌表看起来像这样,因为同一个品牌有多个类别和子类别。请帮我解决这个问题
鉴于您的数据库设计,您可以这样做:
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
但这一切都是不必要的昂贵。如果有一个品牌名称表,以及其他用于类别和子类别 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
然后运行 a DISTINCT
,最后将子类别用作INNER JOIN
基于FIND_IN_SET
。
第一步(“分解”一个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”。他不会得到任何东西 - 没有行会匹配该查询。
恐怕用户界面和工作流程/用例也需要研究。