MYSQL:多对多(Item x_ref属性)WHERE Item不包含Property

时间:2013-03-05 01:36:45

标签: mysql sql

我有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个属性,并且列表可能在将来增长)

任何帮助将不胜感激!感谢。

1 个答案:

答案 0 :(得分:0)

对于简洁和误导性的回复感到抱歉。

再看一遍,我看到UNIONs:

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'

您还要从项目加入item_types,但不对信息执行任何操作(只是确认item.type_id是有效值?)。你可以把它拿掉。

然后,如果你所追求的只是item_id,那么你可以在每次访问item_xref_properties_table时得到它,而不必去项目表,这会使事情变得更好。

希望这更有用。