【问题标题】:How to find duplicate values in mysql table based on ANY y out of x columns where y<=x如何根据y <= x的x列中的任何y在mysql表中查找重复值
【发布时间】:2019-03-15 09:55:53
【问题描述】:

如果任何两列重复,如何在具有三列(col1、col2、col3)的表上查找重复项?

放入伪查询它看起来像这样:

如果col1和col2相同,则选择

如果col2和col3相同,则选择

如果col1和col3相同,则选择

如果 col1,col2 和 col3 相同,则选择

我不想使用“IF”,因为列数实际上大于 10,这会使“IF”查询非常繁琐。

谢谢。

【问题讨论】:

  • 这听起来像XY problem。如果您需要对 10 列进行重复数据删除,那么您可能会使用多对多(但不同)的关系?
  • 请提供样本数据和期望的结果。

标签: mysql sql


【解决方案1】:

注意 我认为您的问题是,如果两个或多个列值相等,则 2 个 被视为重复。如果您只是在 columns 中寻找同一行的重复值,@GordonLinoff 的答案更合适

在 MySQL 中布尔值实际上表示为 0 或 1

对于您的三列示例,条件

(a.col1 = b.col1) + (a.col2 = b.col2) + (a.col3 = b.col3) >= 2

应该做的伎俩

例如,假设您有一个唯一的id 列:

   SELECT *
     FROM your_table a 
    WHERE EXISTS (
     SELECT 1
       FROM your_table b
      WHERE (a.col1 = b.col1) + (a.col2 = b.col2) + (a.col3 = b.col3) >= 2 
        AND a.id != b.id /** Don't consider the same row */
          )

更新

对于 1k 和 130k 之间的大时差,我并不感到惊讶。我想规模将是线性的,因此 15s * 130/1 = 1950s,大约需要 30 分钟来查询整个表。

另外不要忘记,对于每一行,查询都会检查所有其他行是否有重复项。这就是为什么只获取整个表会更快的原因。

我希望您只需要一次性使用此查询来识别受骗者。如果不是,它将指向一些不确定的数据库设计,并且可能会重构该表以更好地适应其目的。这是@apokryfos 在他对您的问题的评论中所指的 XY 问题。

由于条件复杂,上述查询不允许在列上使用任何索引。

假设您在某些列上有单独的索引并且id 是表的 PK,则您可以可能使用UNION ALL 更快地获得结果。

  SELECT base.*
    FROM your_table base
    JOIN (

    SELECT a.id, 1 col_match
      FROM your_table a
     WHERE EXISTS (
      SELECT 1
        FROM your_table b
       WHERE b.col1 = a.col1
         AND b.id != a.id
           )

     UNION ALL

    SELECT a.id, 1 col_match
      FROM your_table a
     WHERE EXISTS (
       SELECT 1
         FROM your_table b
        WHERE b.col2 = a.col2
          AND b.id != a.id
           )

     UNION ALL

    SELECT a.id, 1 col_match
      FROM your_table a
     WHERE EXISTS (
      SELECT 1
        FROM your_table b
       WHERE b.col3 = a.col3
         AND b.id != a.id
           )

         ) raw
      ON raw.id = base.id

GROUP BY base.id
  HAVING SUM(raw.col_match) >= 2

它可能看起来很庞大,但可以轻松地在应用层中为您的十多个列动态构建。

请记住,如果重复项多于唯一项,则颠倒此逻辑可能是有意义的。

【讨论】:

  • 还需要提一下ab是同一张表的别名,需要使用self join。
  • 这不能更动态吗?
  • 谢谢。我试过了,但它看起来像是在比较自己,因此总是正确的。
  • @KeZhao 好的,我会详细说明!抱歉,等着约会太着急了!
  • @Cid 可能,但使用 MySQL 很棘手,感觉像是过度设计。如果有应用层,您可以声明一个数组并从中构建查询
【解决方案2】:

使用 MySQL 的最佳选择可能是:

where col1 in (col2, col3, col4, . . . ) or
      col2 in (col3, col4, . . . ) or
      col3 in (col4, . . . ) or
      . . .

【讨论】:

  • 哇,我可能完全误读了这个问题!我回答了一个完全不同的问题..:P
  • @Arth 。 . .我觉得我明白了。我将这个问题解释为关于同一行中的列。我确实认为这就是 OP 的意图。
  • 虽然说了这么多,但你还没有完全做到,OP想要2个或更多匹配,而不是1个或更多匹配..也许使用我回答中的加法?
  • 谢谢。我认为亚瑟是正确的。我的意思是两行在两列或多列中具有相同的值,然后选择。
  • 我正在考虑一种方法来动态解决它,使用带有SELECT c.COLUMN_NAME FROM myDB.INFORMATION_SCHEMA.COLUMNS c WHERE TABLE_NAME = N'myTable' WHERE c.COLUMN_NAME &lt;&gt; 'someColToExclude' 的子查询或函数来比较某些列与 n 列数
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多