您需要分別檢查每一個,這是EAV模型通常是不好的設計的許多原因之一。你可以通過做兩個子查詢的EXISTS
:
SELECT
P.id, P.name, P.price, P.url -- Because we never use SELECT * except for EXISTS, COUNT(*), etc.
FROM
Products P
WHERE
EXISTS
(
SELECT *
FROM
Products_Attributes PA_RED
INNER JOIN Attributes A_RED ON
A_RED.attribute_id = PA_RED.attribute_id AND
A_RED.description = 'Color' AND -- Have you thought about the possibility that "Red" might be a value for multiple attributes?
A_RED.value = 'Red'
WHERE
PA_RED.product_id = P.product_id
) AND
EXISTS
(
SELECT *
FROM
Products_Attributes PA_XXL
INNER JOIN Attributes A_XXL ON
A_XXL.attribute_id = PA_XXL.attribute_id AND
A_XXL.description = 'Size' AND
A_XXL.value = 'XXL'
WHERE
PA_XXL.product_id = P.product_id
)
你也可以JOIN
到每個表的兩倍:
SELECT
P.id, P.name, P.price, P.url
FROM
Products P
INNER JOIN Products_Attributes PA_RED ON PA_RED.product_id = P.product_id
INNER JOIN Attributes A_RED ON
A_RED.attribute_id = PA_RED.attribute_id AND
A_RED.description = 'Color' AND
A_RED.value = 'Red'
INNER JOIN Products_Attributes PA_XXL ON PA_XXL.product_id = P.product_id
INNER JOIN Attributes A_XXL ON
A_XXL.attribute_id = PA_XXL.attribute_id AND
A_XXL.description = 'Size' AND
A_XXL.value = 'XXL'
當然,想想這個查詢看起來就像當你想檢查5個不同的屬性...
另一種方法是檢查匹配計數作爲一個聚合。您需要確保相同的屬性不能與同一產品兩次匹配:
SELECT
P.id, P.name, P.price, P.url
FROM
Products P
INNER JOIN Products_Attributes PA ON PA.product_id = P.product_id
INNER JOIN Attributes A ON
A.attribute_id = PA.attribute_id AND
(A.description = 'Color' AND A.value = 'Red') OR
(A.description = 'Size' AND A.value = 'XXL')
GROUP BY
P.id, P.name, P.price, P.url
HAVING
COUNT(*) = 2
您確實有點人!謝謝! 你說EAV可能是一個糟糕的設計選擇。你能爲此建議我一個更好的,也許? –
如果你知道你的產品的屬性,然後你把它們放在桌子上:產品會有:顏色,尺寸等。如果你的產品廣泛(你是亞馬遜,你賣書,衣服,電子產品等等與他們自己的屬性),那麼你可能不想使用關係數據庫。像MongoDB或NoSQL這樣的產品可能更合適。這不是我的專業領域,所以其他人可能會有更好的建議。 –
另一種可能性是,如果您有不同的產品,但只有少量類別,則可以使用帶有產品表的模型,然後使用與Product_Electronics,Product_Clothes等1:1關係的模型,只要這些子類型具有相似的屬性即可。 –