如何从具有多个值的EAV结构中选择数据

时间:2017-06-04 03:58:11

标签: mysql

这是我的sql结构

CREATE TABLE IF NOT EXISTS `products` (
  `id` int(11) unsigned NOT NULL,
  `sku` varchar(32) NOT NULL,
  `name` tinytext NOT NULL,
  `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `updated_at` timestamp NULL DEFAULT NULL
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=409 ;

INSERT INTO `products` (`id`, `sku`, `name`, `created_at`, `updated_at`) VALUES
(1, '111', 'Item 1', '', '0000-00-00 00:00:00'),
(2, '222', 'Item 2', '', '0000-00-00 00:00:00'),
(3, '333', 'Item 3', '', '0000-00-00 00:00:00');

CREATE TABLE IF NOT EXISTS `product_attributes` (
`id` int(10) unsigned NOT NULL,
  `attribute_id` int(10) unsigned NOT NULL,
  `value_id` int(10) unsigned NOT NULL,
  `product_id` int(10) unsigned NOT NULL
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=4820 ;

INSERT INTO `product_attributes` (`id`, `attribute_id`, `value_id`, `product_id`) VALUES
(1, 11, 1, 1),
(2, 12, 2, 1),
(3, 13, 3, 1),
(4, 11, 1, 2),
(5, 12, 5, 2),
(6, 13, 6, 2),
(7, 11, 1, 3),
(8, 12, 8, 3),
(9, 13, 3, 3);

我想选择具有n个选定值的产品。例如((attribute_id = 11 AND value_id = 1)AND(attribute_id = 13 AND value_id = 3))。我希望得到产品1和产品。

尝试此查询,但没有运气

select 
    p.id, 
    p.name, 
    pa.attribute_id, 
    pa.value_id 
FROM products p 
JOIN product_attributes pa 
ON p.id=pa.product_id 
WHERE ((pa.attribute_id=11 AND pa.value_id=1) AND (pa.attribute_id=13 AND pa.value_id=3))

2 个答案:

答案 0 :(得分:1)

您需要使用类似于

的解决方案

How to return rows that have the same column values in MySql

但请检查多列

SELECT product_id
FROM product_attributes AS pa
GROUP by product_id
HAVING SUM(pa.attribute_id=11 AND pa.value_id=1) > 0
AND SUM(pa.attribute_id=13 AND pa.value_id=3) > 0

另一个解决方案是加入每组值的查询。

SELECT pa1.product_id
FROM product_attributes AS pa1
JOIN product_attributes AS pa2 ON pa1.product_id = pa2.product_id
WHERE pa1.attribute_id=11 AND pa1.value_id=1
AND pa2.attribute_id=13 AND pa2.value_id=3

答案 1 :(得分:0)

根据您的问题中的查询,where子句永远不会成立,因为对于单行,attribute_id将永远不会等于11和13,而value_id = 1和3。

试试这个:

select 
    p.id, 
    p.name, 
    pa1.attribute_id, 
    pa1.value_id, 
    pa2.attribute_id, 
    pa2.value_id 
FROM products p 
JOIN product_attributes pa1 
ON p.id = pa1.product_id 
JOIN product_attributes pa2 
ON p.id = pa2.product_id 
WHERE ((pa1.attribute_id=11 AND pa1.value_id=1) AND (pa2.attribute_id=13 AND pa2.value_id=3))

它连接到属性表两次,因此您可以分离这两个条件并测试两者是否为真。