MYSQL:多对多(Item x_ref属性),其中Item不包含属性
我有三张桌子;一个项目表、一个属性表和一个x_ref表,该表将项目链接到属性,还包含该属性的值: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`
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,但我不能把它们全部放在一起。还有其他提示吗?