MYSQL:多对多(Item x_ref属性),其中Item不包含属性

MYSQL:多对多(Item x_ref属性),其中Item不包含属性,mysql,sql,Mysql,Sql,我有三张桌子;一个项目表、一个属性表和一个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`

我有三张桌子;一个项目表、一个属性表和一个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多个属性,并且列表可能在将来增长)


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

很抱歉,你的回答既简洁又有误导性

再看一遍,我看到工会:

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_类型,但对信息不做任何处理(只是确认item.type_id是有效值?)。你可以把它拿出来

然后,如果您所追求的只是项目id,则每次访问项目外部参照属性表时都可以获得该id,而无需访问项目表,这将使事情变得更好


希望这更有用。

提示:“OUTER”连接和“CASE”语句。嗯,不确定在哪里使用“CASE”。我认为应该在Properties表上有一个外部连接,然后测试null,但我不能把它们全部放在一起。还有其他提示吗?