鉴于您的数据库设计,您可以这样做:
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”。他不会得到任何东西 - 没有行会匹配该查询。
恐怕用户界面和工作流程/用例也需要研究。