2012-02-15 15 views
0

いくつかのカスタムパラメータに一致する製品を取得しようとしています。 製品、パラメータ、パラメータ項目の3つのテーブルが必要です。列を複数の値と照合して2つのテーブルを結合する

製品テーブル:

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; 

だから私の質問は、私はすべてのパラメータに一致する製品のみを得ることができる方法であります。

私が考えることができる唯一の方法は、数回のパラメータ項目テーブルに参加することです。 は例えば、ここでは2つのパラメータをマッチした製品を取得するためのクエリです:

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

少しのテストの後、私はこの方法が最速の方法だと言うことができます。どうもありがとう :) –

2

はIN句にリストされている値の数と一致するように、HAVING句にテストされた値を調整していただきありがとうございます。

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)を使用しません。私もそれを強制しようとしたが、私はまだ同じ結果を得る。 –

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の対応する行を削除せずにパラメータを削除すると偽になる可能性がありますが、これは制約条件です)

関連する問題