加入两个表,匹配具有多个值的列

时间:2012-02-15 15:32:17

标签: mysql join

我正在尝试获得与某些自定义参数匹配的产品。 所以我需要三个表 - 产品,参数和参数项。

产品表:

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查询将变得越来越慢。 那么有更好的方法来处理这个问题吗?

谢谢

3 个答案:

答案 0 :(得分: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)

答案 1 :(得分:1)

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

答案 2 :(得分: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中的相应行,这可能会变得虚假。这就是约束条件。)