【问题标题】:How to select data from EAV structure with multiple values如何从具有多个值的 EAV 结构中选择数据
【发布时间】:2017-06-04 03:58:10
【问题描述】:

这是我的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 和 3。

试试这个查询,但没有成功

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))

【问题讨论】:

  • 那么,就您的 SQL 语句而言,您尝试过什么?
  • 对每个值使用子查询,然后将它们连接起来以获取包含所有这些值的产品。
  • @SloanThrasher,更新我的问题
  • @Barmar,我不确定我是否理解你。你的意思是这样的JOIN (select p.id, p.name, pa.attribute_id, pa.value_id WHERE (pa.attribute_id=11 AND pa.value_id=1))

标签: mysql


【解决方案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

【讨论】:

  • 谢谢!你能给出你的建议,哪个查询最快?
  • 我想,HAVING 会减慢最终查询的速度,对吗?
  • 是的。第一个查询对所有数据进行大量聚合,然后将其过滤到所需的行。第二个可以使用索引来查找行,然后将它们配对。
【解决方案2】:

对于您在问题中的查询,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))

它两次加入属性表,因此您可以将两个条件分开并测试两者是否为真。

【讨论】:

  • 谢谢!它也适合我。
猜你喜欢
  • 1970-01-01
  • 2010-09-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-30
  • 1970-01-01
相关资源
最近更新 更多