我有一个由group_id(PK)和其他一些字段定义的组表(GROUPS)。 每个组可以包含可变数量的元素及其值。该组合成存储在第二个表(GROUP_COMPOSITION)中,该表具有PK字段(计数器),group_id的字段,元素名称的字段和元素名称值的字段。
例如:
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
因此,如果试图插入由Material = B和Color = white和Temperature = 50专门定义的“新组”(g5),我想将其识别为重复组(g2)。
我想防止在第二个表中插入重复的“组合成”,其中组合由元素总数及其值定义。
我正在考虑插入所有可能元素的INTERSECT查询,但不确定这是否是最佳方式。
这与帖子SQL to find duplicate entries (within a group)有关,但在这种情况下,查找重复插入的条件是基于元素的数量(而不是其性质)。
我真的很感激任何帮助
由于
答案 0 :(得分:1)
我想我会建立一个功能并走向交叉路线。我想你也可以构建一个字符串,将每个组与表示所有组数据的值相关联。然后将相同的函数应用于候选组并检查元素的匹配。这是一个可能的aggegation的Postgresql示例:
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 :(得分: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
如果有任何返回的行,那么您已经拥有一个至少具有这些属性的组。