2012-02-15 74 views
0

我试图让产品符合一些自定义的参数相匹配的列。 所以我有三个表格 - 产品,参数和参数项目。加入两个表,具有多个值

产品表:

CREATE TABLE `products` (
    `ID` int(10) unsigned NOT NULL AUTO_INCREMENT 
    `Title` varchar(255) COLLATE utf8_unicode_ci NOT NULL, 
    `Content` longtext COLLATE utf8_unicode_ci NOT NULL, 
    `Price` float(10,2) unsigned NOT NULL, 
    PRIMARY KEY (`ID`) 
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; 

参数表:

CREATE TABLE `parameters` (
    `ID` int(10) unsigned NOT NULL AUTO_INCREMENT, 
    `Label` varchar(80) COLLATE utf8_unicode_ci NOT NULL, 
    PRIMARY KEY (`ID`) 
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; 

参数项表:

CREATE TABLE `parametersitems` (
    `ProductID` int(10) unsigned NOT NULL DEFAULT '0', 
    `ParameterID` int(10) unsigned NOT NULL DEFAULT '0', 
    PRIMARY KEY (`ProductID`,`ParameterID`), 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; 

所以我的问题是我怎么能得到的不仅是产品的所有参数匹配。

我能想到的唯一的办法就是加入parameteritems表几次。 例如,这里是一个查询来获取产品配套两个参数:

SELECT 
    products.* 
FROM 
    products 

INNER JOIN 
    parametersitems AS paritems1 
    ON 
     paritems1.ItemID = products.ID 
     AND paritems1.ParameterID = 7 

INNER JOIN 
    parametersitems AS paritems2 
    ON 
     paritems2.ItemID = products.ID 
     AND paritems2.ParameterID = 11 

我唯一担心的是,如果选择有多个参数SELECT查询会得到越来越慢。 那么有没有更好的方法来处理这个问题?

谢谢

回答

0
select p.* 
from products p 
inner join (
    select ItemID 
    from parametersitems 
    where ParameterID in (7, 11) 
    group by ItemID 
    having count(distinct ParameterID) = 2 
) pm on p.ID = pm.ItemID 
+0

经过一些测试后,我可以说这种方法是最快的。非常感谢 :) – 2012-02-16 09:17:42

2

调整HAVING子句中的测试,以符合IN子句中列出值的数量值。

SELECT p.* 
    FROM products p 
    WHERE p.ID IN (SELECT pi.ItemID 
         FROM parameteritems pi 
         WHERE pi.ItemID = p.ID 
          AND pi.ParameterID IN (7,11) 
         GROUP BY pi.ItemID 
         HAVING COUNT(DISTINCT pi.ParameterID) = 2) 
+0

谢谢您的回答。它工作得很好,但使用上面提到的INNER JOIN方法会更慢。出于某种原因,当我解释查询时,它不使用PRIMARY INDEX(products.ID)。我甚至试图强制它,但我仍然得到相同的结果。 – 2012-02-16 09:09:00

0
SELECT 
    p.ID, p.Title, p.Content, p.Price 
FROM 
    products AS p 
INNER JOIN 
    parametersitems AS pi ON pi.ProductID = p.ID 
GROUP BY 
    p.ID, p.Title, p.Content, p.Price 
HAVING COUNT(DISTINCT pi.ParameterID) = (SELECT COUNT(ID) FROM parameters); 

这总是会得到你的产品每一个参数匹配,不管你有多少参数添加。 (如果你删除一个参数,而在paramatersitems删除相应的行。这可能成为伪造的。这是约束是。)