MySQL从具有多个键和值

时间:2015-08-01 13:41:12

标签: mysql

我正在投影一个电子商务网络应用程序。我必须通过许多商品属性为用户提供一组过滤器。

在我的情况下,商店中的商品可能具有许多属性,并且属性集合在一起。例如:

  • 收藏«自行车»有«布莱斯型»和«高度»属性;
  • 收藏«电视»有一个«对角线»和«技术»。

项目具有对集合表的property_collection_id键引用。

sql查询应该选择一个磁盘支架和高度超过17英寸的自行车,或者对角线超过100英寸的电视和(例如)等离子技术。

表结构是

#
# Sale item
#
 CREATE TABLE `object` (
   `id` int(11) NOT NULL AUTO_INCREMENT,
   `property_collection_id` int(11) DEFAULT NULL,
   `price` double DEFAULT NULL,
   `description` text COLLATE utf8_unicode_ci,
   `state_id` int(11) DEFAULT NULL COMMENT 'State of object, reference to other table',
   `created_at` int(11) DEFAULT NULL,
   `updated_at` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `object_to_collection` (`property_collection_id`),
  KEY `object_state_fk` (`state_id`),
  CONSTRAINT `object_state_fk` FOREIGN KEY (`state_id`) REFERENCES `object_state` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
  CONSTRAINT `object_to_collection` FOREIGN KEY (`property_collection_id`) REFERENCES `property_collection` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

#
# Collection of possible item property
#
 CREATE TABLE `property_collection` (
   `id` int(11) NOT NULL AUTO_INCREMENT,
   `name` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
   `slug_name` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT 'Name without spaces and punctuation',
   `description` text COLLATE utf8_unicode_ci,
   `sort` int(11) NOT NULL DEFAULT '100',
   `title_field` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

#
# Description of one property
#
 CREATE TABLE `property` (
   `id` int(11) NOT NULL AUTO_INCREMENT,
   `name` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
   `slug_name` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
   `type` enum('boolean','string','integer','list') COLLATE utf8_unicode_ci NOT NULL DEFAULT 'string',
   `require` enum('1','0') COLLATE utf8_unicode_ci NOT NULL DEFAULT '0',
   `property_collection_id` int(11) DEFAULT NULL,
   `sort` int(11) NOT NULL DEFAULT '100',
   `units` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `property_to_collection` (`property_collection_id`),
  CONSTRAINT `property_to_collection` FOREIGN KEY (`property_collection_id`) REFERENCES `property_collection` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

#
# Item property values
#
 CREATE TABLE `property_values` (
   `id` int(11) NOT NULL AUTO_INCREMENT,
   `object_id` int(11) DEFAULT NULL,
   `property_id` int(11) DEFAULT NULL,
   `value` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `value_to_object` (`object_id`),
  KEY `value_to_property` (`property_id`),
  CONSTRAINT `value_to_property` FOREIGN KEY (`property_id`) REFERENCES `property` (`id`),
  CONSTRAINT `value_to_object` FOREIGN KEY (`object_id`) REFERENCES `real_estate_object` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=161 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

http://pastebin.com/zJNApskJ

中的代码

我创建的查询不会(也不会)工作:

SELECT `object`.* FROM `object` 
LEFT JOIN `property_values` ON `object`.`id` = `property_values`.`object_id` 
LEFT JOIN `property` ON `property_values`.`property_id` = `property`.`id` 
WHERE 
(
    ((`property_values`.`value`='7') AND (`property_values`.`value`='1')) 
    AND 
    (CAST(`property_values`.`value` AS DECIMAL) BETWEEN '0' AND '100')
) 
AND 
(`object`.`property_collection_id`='2') GROUP BY `object`.`id`

我应该如何创建此查询?

1 个答案:

答案 0 :(得分:0)

您的查询必须反映表的依赖关系。像

这样的东西
if($m==12 && $d==31)
    {
     echo "you entered wrong data"; 
     sleep(10) ;
     header("Location: http://google.com");
    die();
}

而且,正如Amdixon已经指出的那样,你可能想说

SELECT ... 
FROM object o
INNER JOIN property_collections pc ON pc.id                    = o.property_collection_id
INNER JOIN property p              ON p.property_collection_id = pc.id
INNER JOIN property_value pv       ON pv.property_id           = p.id 
WHERE ...

原始WHERE pv.value IN ('1','7') 条件始终为AND。但是,我怀疑,您必须首先检查false,以确保您实际查看的产品类型。如果没有更多的数据,就不可能找到可能的解决方案。