0

私は3つのテーブルを持っています。アイテムのテーブル、プロパティのテーブル、およびアイテムをプロパティにリンクし、そのプロパティの値も含むx_refテーブル。

CREATE TABLE IF NOT EXISTS `items` (
  `item_id` INT(11) NOT NULL AUTO_INCREMENT,
) ENGINE=InnoDB DEFAULT CHARSET=utf8 row_format=COMPRESSED; 

CREATE TABLE IF NOT EXISTS `properties` (
  `property_id` INT(11) NOT NULL AUTO_INCREMENT,
  `property_name` VARCHAR(255) NOT NULL,    
) ENGINE=InnoDB DEFAULT CHARSET=utf8 row_format=COMPRESSED;

CREATE TABLE IF NOT EXISTS `item_xref_properties` (
  `item_id` INT(11) NOT NULL,
  `property_id` INT(11) NOT NULL,   
  `property_value` DECIMAL(8,1) NOT NULL,
  PRIMARY KEY  (`item_id`,`property_id`),
  INDEX (`item_id`),
  INDEX (`property_id`),
  INDEX (`property_value_1`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 row_format=COMPRESSED;

私はこのようなクエリを持っています:

プロパティ「A」、「B」、および「C」を含むすべてのアイテムをフェッチします。「A」は100〜200、「B」は50〜80、「C」は10〜30です。

これは次のように解釈されます。

SELECT itm.item_id 
FROM items itm 
    JOIN item_types ityp 
        ON itm.type_id = ityp.type_id
   JOIN item_xref_properties ixp1 
        ON itm.item_id = ixp1.item_id 
            AND ixp1.property_value 
            BETWEEN '100' AND '200' 
   JOIN properties prop1 
        ON ixp1.property_id = prop1.property_id 
            AND prop1.property_name = 'Property A' 
   JOIN item_xref_properties ixp2 
        ON itm.item_id = ixp2.item_id 
            AND ixp2.property_value 
            BETWEEN '50' AND '80' 
   JOIN properties prop2 
        ON ixp2.property_id = prop2.property_id 
            AND prop2.property_name = 'Property B' 
   JOIN item_xref_properties ixp3 
        ON itm.item_id = ixp3.item_id 
            AND ixp3.property_value_1 
            BETWEEN '10' AND '30' 
   JOIN properties prop3 
        ON ixp3.property_id = prop3.property_id 
            AND prop3.property_name = 'Property C'

少しエレガントでない場合はかなり簡単です。

私の問題は、上記のようにこのテーブルをクエリし、次のようなプロパティが指定されていないアイテムを見つける必要があることです。

プロパティ「A」、「B」、および「C」を含むすべてのアイテムをフェッチします。「A」は100〜200、「B」は50〜80、「C」は10〜30ですが、プロパティ「D」は含まれません。 'または'E '

私はこれを機能するクエリに変換するために多くの方法を試しましたが、役に立ちませんでした。これも可能ですか?または、テーブルをフラット化し、プロパティごとにアイテムテーブルに個別の列を設定する必要があります(100を超えるプロパティがあり、リストは将来大きくなる可能性があるため、理想的ではありません)。

どんな助けでも大歓迎です!ありがとう。

4

1 に答える 1

0

簡潔で誤解を招くような回答で申し訳ありません。

もう一度見てみると、UNION が表示されます。

SELECT itm.item_id 
FROM items itm 
    JOIN item_types ityp 
        ON itm.type_id = ityp.type_id
   JOIN item_xref_properties ixp1 
        ON itm.item_id = ixp1.item_id 
            AND ixp1.property_value 
            BETWEEN '100' AND '200' 
   JOIN properties prop1 
        ON ixp1.property_id = prop1.property_id 
            AND prop1.property_name = 'Property A' 
UNION
SELECT itm.item_id 
FROM items itm 
    JOIN item_types ityp 
        ON itm.type_id = ityp.type_id
    JOIN item_xref_properties ixp2 
        ON itm.item_id = ixp2.item_id 
            AND ixp2.property_value 
            BETWEEN '50' AND '80' 
   JOIN properties prop2 
        ON ixp2.property_id = prop2.property_id 
            AND prop2.property_name = 'Property B' 
UNION
SELECT itm.item_id 
FROM items itm 
    JOIN item_types ityp 
        ON itm.type_id = ityp.type_id
    JOIN item_xref_properties ixp3 
        ON itm.item_id = ixp3.item_id 
            AND ixp3.property_value_1 
            BETWEEN '10' AND '30' 
   JOIN properties prop3 
        ON ixp3.property_id = prop3.property_id 
            AND prop3.property_name = 'Property C'

また、items から item_types に参加していますが、情報を使って何もしていません (item.type_id が有効な値であることを確認するだけですか?)。あなたはおそらくそれを取り出すことができます。

次に、必要なのが item_id だけである場合は、items テーブルにまったくアクセスしなくても、item_xref_properties_table にアクセスするたびにそれを取得できます。

それがもっと役立つことを願っています。

于 2013-03-05T19:46:31.160 に答える