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'

您还从项目加入到 item_types,但对信息不做任何事情(只是确认 item.type_id 是有效值?)。你可能可以把它拿出来。

然后,如果您所追求的只是 item_id,那么您可以在每次访问 item_xref_properties_table 时获得它,而无需访问 items 表,这会使事情变得更好。

希望这更有用。

于 2013-03-05T19:46:31.160 回答