如何对一列或多列相等的行进行分组?

时间:2014-01-08 20:29:03

标签: mysql sql group-by

假设我有一个包含以下列的产品数据库:

name
isbn
ean
upc
sku

如果这些列匹配,我想将产品分组。我怎么能这样做?

我尝试使用GROUP BY子句,但显然这意味着列的所有必须匹配,而不仅仅是一个。

换句话说,当{em>所有列相等时,GROUP BY name, isbn, ean, upc, sku仅将产品分组在一起,如果任何,我希望将它们组合在一起列是相等的。

示例:

id  |  name   |     isbn     |  ean  |    upc     | sku
 0    banana1       null        null   0000000000   1234
 1    banana2       6789        null   0000000000   1234 
 2    banana3       6789        null   1111111111   null
 3    banana4       null        null   1111111111   null

所有这些行应该组合在一起,因为它们至少有一个相互匹配的列。

2 个答案:

答案 0 :(得分:2)

不。 GROUP BY要求分组表达式中的所有元素在该组中的行之间相同。我能想到的最好的是:

SELECT
  *
FROM
  table
WHERE
  name = isbn 
  OR name = ean
  OR name = upc
  OR name = sku
  OR isbn = ean
  OR isbn = upc
  OR isbn = sku
  OR ean = upc
  OR ean = sku
  OR upc = sku

正如您所看到的,缺点是这非常难看,并且在添加新列时不能很好地扩展。我只会使用它,如果它是一个一次性的脚本 - 例如,识别数据损坏。

答案 1 :(得分:1)

这是一个图形遍历问题,在SQL中实现很痛苦 - 尤其是MySQL,它不支持分层查询。

有一个不太糟糕的迭代解决方案。我们的想法是添加一个“groupid”列,然后不断更新。更新的规则是首先使用id填充它,然后沿任何维度为其分配最小值。以下是代码示例:

update products
    set groupid = id;

/* now run this multiple times until there are no more updates */
update products p
    set groupid = (select min(groupid)
                   from products p2
                   where p.name = p2.name or
                         p.isbn = p2.isbn or
                         p.ean = p2.ean or
                         p.upc = p2.upc or
                         p.sku = p2.sku
                 );