Объединить две таблицы, сопоставив столбец с несколькими значениями - PullRequest
0 голосов
/ 15 февраля 2012

Я пытаюсь получить товар, соответствующий некоторым пользовательским параметрам. Поэтому у меня есть три таблицы - продукты, параметры и параметры элементов.

Таблица продуктов:

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;

Так что мой вопрос: как я могу получить только продукты, соответствующие всем параметрам.

Единственный способ, которым я мог придумать, - это присоединиться к таблице параметров параметров пару раз. Например, вот запрос для получения продуктов, соответствующих двум параметрам:

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 ]

2 голосов
/ 15 февраля 2012

Настройте значение, проверенное в предложении 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 голос
/ 15 февраля 2012
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 голосов
/ 15 февраля 2012
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. Это то, для чего нужны ограничения.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...