SQL:在组中查找重复条目(具有可变数量的元素)

时间:2011-12-02 18:02:47

标签: sql oracle oracle10g

我有一个由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)有关,但在这种情况下,查找重复插入的条件是基于元素的数量(而不是其性质)。

我真的很感激任何帮助

由于

2 个答案:

答案 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

如果有任何返回的行,那么您已经拥有一个至少具有这些属性的组。