2009-06-29 78 views
2

我有一個PRODUCTS表,每個產品可以有多個屬性,所以我有一個ATTRIBUTES表和另一個名爲ATTRIBPRODUCTS的表位於中間。這些屬性按類別(類型,品牌,材料,顏色等)分組,因此人們可能需要特定品牌的特定類型的產品。實現此SQL查詢的最佳方式是什麼?

PRODUCTS 
product_id 
product_name 

ATTRIBUTES 
attribute_id 
attribute_name 
attribute_class 

ATTRIBPRODUCTS 
attribute_id 
product_id 

當某人正在尋找一種產品,他們可以選擇一個或多個屬性。我遇到的問題是返回具有多個屬性的單個產品。這應該是非常簡單的我知道,但SQL真的不是我的事情,並且在邏輯上我有點失落了。問題是我想檢查每個屬性類分開,所以我想是這樣結束了:

SELECT DISTINCT products.product_id 
FROM   attribproducts 
INNER JOIN products ON attribproducts.product_id = products.product_id 
WHERE  (attribproducts.attribute_id IN (9,10,11) 
AND  attribproducts.attribute_id IN (60,61)) 

我已經用在不同類別的屬性的塊分開的,所以我結束了特定類型的產品,以及某些品牌的產品。從我得到的結果看來,導致問題的IN語句之間似乎是這樣。

任何人都可以幫忙嗎?不幸的是,我沒有完全重構數據庫的好處,除此之外還有很多其他的東西,所以對於如何使用我所擁有的東西的任何建議都會感激不盡。

回答

3

看看SQL: Many-To-Many table AND query這個問題的答案。這是完全一樣的問題。 Cletus給出了兩種可能的解決方案,其中沒有一個非常微不足道(但是再一次,沒有簡單的解決方案)。

+0

但這看起來非常相似 - 一個很好的反正起點。感謝所有回答的人 – Dave 2009-06-29 12:25:41

0

試試這個:

select * from products p, attribproducts a1, attribproducts a2 
    where p.product_id = a1.product_id 
    and p.product_id = a2.product_id 
    and a1.attribute_id in (9,10,11) 
    and a2.attribute_id in (60,61); 
0

這將不返回行,因爲你只計算有一個數字,就是(或9,10,11)和(60或者61)行。

因爲這些集合不相交,您將不會獲得行。

如果您使用OR,它會爲產品提供屬性集9,10,11,60,61,這兩個屬性都不是您想要的,但您會獲得多行每個產品。

您可以將該select用作GROUP BY語句中的子查詢,按產品數量進行分組,然後按共享屬性的數量進行分組。這會首先給你最高的比賽。

或者(如另一個答案所示),您可以加入每個屬性集的表的新副本,只給出與所有屬性集匹配的產品。

1
SELECT DISTINCT products.product_id 
FROM products p 
INNER JOIN attribproducts ptype on p.product_id = ptype.product_id 
INNER JOIN attribproducts pbrand on p.product_id = pbrand.product_id 
WHERE ptype.attribute_id IN (9,10,11) 
    AND pbrand.attribute_id IN (60,61) 
0

這聽起來像你有一個偉大的數據模式存儲,但選擇/報告很糟糕。當你有一個OBJECT,ATTRIBUTE,OBJECT-ATTRIBUTE和OBJECT-ATTRIBUTE-VALUE的數據結構時,你可以爲每個對象存儲許多具有許多不同屬性的對象。這有時被稱爲「垂直存儲」。

但是,當您想要檢索具有所有屬性值的對象列表時,它必須是可變數量的連接。當數據在水平存儲時更容易檢索數據(定義的數據列)

我已經遇到了這種情況多次。由於您無法更改現有的數據結構。我的建議是在頂部寫一個「層」的表格。動態創建每個對象/產品的表格。然後在每個屬性的新表中動態創建靜態列。幾乎你需要將垂直存儲的屬性/值「扁平化」爲靜態列。從垂直架構轉換爲水平架構。

使用「拼合」表進行報告,並使用垂直表進行存儲。

如果您需要示例代碼或更多詳細信息,請問我。

我希望這很清楚。我沒有太多的咖啡卻:)

謝謝, - 馬克

0

您可以使用多個內部連接 ​​- 我認爲這會工作:

select distinct product_id 
from products p 
inner join attribproducts a1 on a1.product_id=p.product_id 
inner join attribproducts a2 on a1.product_id=p.product_id 
where a1.attribute_id in (9,10,11) 
    and a2.attribute_id in (60,61) 
相關問題