问题:我想选择 option_value_id 为 1 和 3 的产品。但是,如您所见,它还会显示只有 option_value_id 中的 1 个的产品。
我尝试添加 AND 而不是 IN 但这显然不会显示任何结果。
答案可能很简单,但我现在似乎无法弄清楚。有人可以帮我吗?即使是一个小提示也可以理解。
这称为Relation Division,这是一种方法:
SELECT *
FROM TABLEName
WHERE Product_ID IN(SELECT Product_ID
FROM Tablename
WHERE option_value_id IN(1, 3)
GROUP BY Product_ID
HAVING COUNT(option_value_id) = 2);
这会给你:
| ID | PRODUCT_ID | OPTION_VALUE_ID |
-------------------------------------
| 1 | 1 | 1 |
| 3 | 1 | 3 |
| 13 | 2 | 3 |
| 14 | 2 | 1 |
这是将事物视为一组的示例。我认为最好的方法是使用 SQL 的聚合,尤其是 having 子句。在 MySQL 语法中,这看起来像:
select pa.product_id
from Product_Attributes pa
group by pa.product_id
having max(pa.option_value_id = 1) = 1 and
max(pa.option_value_id = 3) = 1
这是一个常见的问题,叫做Relational Division,在SO中甚至有一个标签:sql-match-all
通常, 有一个唯一约束(product_id, option_value_id)
,因此一种解决方案是使用 2 个连接(如果要检查 N 个属性,则使用 N 个连接):
SELECT p.* -- whatever columns you need
FROM product AS p -- from the `product` table
JOIN products_attributes AS pa1
ON pa1.option_value_id = 1
AND pa1.product_id = p.product_id
JOIN products_attributes AS pa2
ON pa2.option_value_id = 3
AND pa2.product_id = p.product_id ;
有一个类似的问题,有超过 10 种不同的方法来实现相同的结果(以及 Postgres 的基准):How to filter SQL results in a has-many-through relationship
试试这个:
SELECT *
FROM products_attributes
WHERE option_value_id IN (1, 3)
GROUP BY product_id
HAVING COUNT(*) = 2