我有像这样的表
- Products: PID,ProductName...
- Attributes:AID,AttributeName...
- ProductAttributes:PID,AID,Value
,值为
***ProductAttributes***
- P1,A1,V1
- P1,A2,V2
- P1,A3,V3
- P2,A1,V4
- P2,A2,V2
- P2,A3,V3
- P3,A1,V1
- P3,A2,V2
- P3,A3,V5
我需要一个具有2个数组参数的过程,并按照这些参数过滤产品。如果Parameter1:{A1,A2}
和Parameter2:{V1,V2}
程序应选择
P1,P3
我怎么写这个?感谢
答案 0 :(得分:0)
我假设V1必须是属性A1的值,V2必须是属性A2的值。换句话说,如果您搜索具有属性('canvascolor','solecolor')和值('red','black')的鞋子,那么您不需要带有黑色帆布和红色鞋底的鞋子。
无论何时想要比较WHERE表达式中的多个属性,它们都需要位于同一行。如果您使用传统的关系表设计,这将很容易,其中每个属性都存储在一个不同的列中:
SELECT p.*
FROM Products p
WHERE p.canvascolor = 'red' AND p.solecolor = 'black';
您也可以使用元组比较来编写此表达式:
SELECT p.*
FROM Products p
WHERE (p.canvascolor, p.solecolor) = ('red', 'black');
当您在多个行上存储属性时,就像在您使用的Entity-Attribute-Value表中一样,事情变得更加复杂。这是具有灵活性的权衡,EAV允许您随意定义属性。您需要使用连接将这些连接放到同一行,以便进行比较:
SELECT p.*
FROM Products p
JOIN ProductAttributes pa1 ON pa1.PID = p.PID
JOIN Attributes a1 ON a1.AID = pa1.AID
JOIN ProductAttributes pa2 ON pa2.PID = p.PID
JOIN Attributes a2 ON a2.AID = pa2.AID
WHERE (a1.AttributeName, pa1.Value) = ('A1', 'V1')
AND (a2.AttributeName, pa2.Value) = ('A2', 'V2');
另一种方法是匹配 属性/值对,然后按匹配的PID进行分组。匹配计数恰好为两个的组具有所需的属性&值。
SELECT p.PID, MAX(p.ProductName), ...
FROM Products p
JOIN ProductAttributes pa ON pa.PID = p.PID
JOIN Attributes a ON a.AID = pa.AID
WHERE (a.AttributeName, pa.Value) = ('A1', 'V1')
OR (a.AttributeName, pa.Value) = ('A2', 'V2')
GROUP BY p.PID
HAVING COUNT(*) = 2;