根据我的系统,我需要根据类别和子类别搜索品牌。
像这样的品牌表
id brandname categoryid subcategoryid
1 xys 1,2,3 1,5,6
现在当我搜索我选择类别然后根据类别所有子类别来现在我选择子类别现在需要显示基于该类别和子类别的所有品牌。 我的品牌表看起来像这样,因为同一品牌有多个类别和子类别。请帮我解决这个问题
答案 0 :(得分:4)
鉴于您的数据库设计,您可以这样做:
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
代替{{1来限制两个类别中的项目}}
但这一切都是不必要的昂贵。您可以通过拥有品牌名称表,类别和子类别ID的其他表格以及链接来做得更好:
OR
通过这种方式,您可以运行更快的查询,而不会遇到诸如无法将文章分配给“太多”类别(例如50)的问题;如果你想把一篇文章从一个类别转移到另一个类别,那么你的当前设计几乎是不可能的。
我这样搜索起初我选择了所有子类别的类别 来自类别。然后当我选择子类别所有的品牌 基于该类别和子类别来。现在我添加一个品牌名称 一次有多个类别和多个子类别。
我必须说,“噢,我的上帝”。为了能够“选择所有子类别”/ now /,您必须转换此
// 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;
在 5 1 5 7 5 9 5 19 5 7 5 9 5 11
然后运行 category subcategory
4,5 1,7,9,19
5 7,9,11
,最后根据DISTINCT
将子类别用作INNER JOIN
。
第一步(“爆炸”CSV行)可以像这样完成:http://www.marcogoncalves.com/2011/03/mysql-split-column-string-into-rows/ ...正如你所看到的那样,这一切都是微不足道的。
我希望你现在正在用PHP进行拆分。
这样做之后,FIND_IN_SET
非常昂贵。
我们在糟糕的情况下投入了大量资金。您当前的数据库设计不允许轻松地执行您想要的操作。最简单的方法是:
INNER JOIN
上述查询也可能根本不返回。。假设您查找子类别5和类别12.根据您的请求,获取“所有子类别”和“所有类别”也可能返回品牌6和子类别9.然后这两行出来,
// 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 );";
并且用户选择“Marlboro 6 12”。他不会得到任何东西 - 没有行会匹配该查询。
我担心用户界面和工作流程/用例也需要查看。