2011-12-02 42 views
3

我有一個由group_id(PK)和其他一些字段定義的組(GROUP)表。 每個組可能包含可變數量的元素及其值。該組合物存儲在具有PK字段(計數器),用於group_id的字段,用於元素名稱的字段和用於元素名稱的值的字段的第二個表(GROUP_COMPOSITION)中。SQL:查找組中的重複條目(具有可變數量的元素)

例如:

Table of groups: 
groupId 
g1 
g2 

Table of Group composition: 

PK  groupID  Element_Name Element_Value 
1  g1   Material  A 
2  g1   Temperature  37 
3  g2   Color   white 
4  g2   Temperature  50 
5  g2   Material  B   
6  g3   Material  C 
7  g4   Color   Red 

所以,如果試圖插入由材料= B和顏色=白色和溫度= 50只定義的「新組」(G5),我想將其識別爲重複組(g2)。

我想阻止在第二個表中插入重複的「組合」插入,其中組合構成由元素及其值的總數定義。

我想插入所有可能的元素的INTERSECT查詢,但不知道這是否是最佳方式。

這與帖子SQL to find duplicate entries (within a group)有關,但在這種情況下,查找重複插入的標準是基於元素的數量(而不是其性質)。

我真的apprettiate任何幫助

感謝

+1

如果您提供了一些示例數據,它會更容易理解您問的問題... – wweicker

+0

謝謝,示例添加(希望它有幫助...) – user1074360

+1

很好的問題,顯示爲什麼EAV很難。你確切知道有多少元素? –

回答

1

我想我會建立一個功能並交叉點的路線。我想你也可以建立一個字符串,將每個組與一個代表所有組數據的值相關聯。然後將相同的功能應用於候選組,並檢查元素上的匹配。下面是一個Postgresql示例的可能的aggegation:

SELECT g.groupid, array_to_string(g.element_array, ',') elements 
    FROM (SELECT o.groupid, array_agg(o.element_name ||'='|| o.element_value) AS element_array 
     FROM (SELECT groupid, element_name, element_value 
       FROM composition 
       ORDER BY 1, 2) o 
     GROUP BY groupid) g 
    ORDER BY groupid 


groupid |   elements 
---------+--------------------------------------- 
g1  | Material=A,Temperature=37 
g2  | Color=white,Material=B,Temperature=50 
g3  | Material=C 
g4  | Color=Red 

內部排序是爲了確保它一致地生成。看起來Oracle 11gR2有一個LISTAGG函數可以用於字符串連接。或者你可以建立你自己的聚合函數來做到這一點。如果此數據相對靜態,則可能需要預先計算並在插入時存儲,而不是每個查詢都重新生成。

1

由於您的數據似乎表明這些羣體中存在相當穩定的屬性範圍,爲什麼不讓他們成爲一等公民,而是將他們提升爲專欄?

groupid | Material | Temperature | Color 
--------+----------+-------------+----------- 
g1  | A  | 37   | <null> 
g2  | B  | 50   | White 
g3  | C  | <null>  | <null> 
g4  | <null> | <null>  | Red 

它不會太難動態地根據需要添加,如果你實在是太斜柱,但我有點好奇,你想如何定義一組爲「重複」?每當新組的屬性在現有組中具有至少一個對應的屬性時?如果是這樣,查詢將非常簡單:

select groupid from table where 
Material=B and 
Color=White 

如果有任何返回的行,那麼您已經有一個至少具有這些屬性的組。