Как найти повторяющиеся значения в таблице MySQL на основе ЛЮБОГО y из x столбцов, где y <= x - PullRequest
0 голосов
/ 10 октября 2018

как найти дубликаты в таблице с тремя столбцами (col1, col2, col3), если ЛЮБЫЕ два столбца имеют дубликат?

вставьте псевдопросмотр, он будет выглядеть следующим образом:

Если col1 и col2 одинаковы, выберите

, если col2 и col3 совпадают, затем выберите

, если col1 и col3 одинаковы, затем выберите

, если col1, col2 и col3 одинаковы, затем выберите

Я не хочу использовать 'IF', потому чтоколичество столбцов на самом деле больше 10, что делает запрос 'IF' очень утомительным.

спасибо.

Ответы [ 2 ]

0 голосов
/ 10 октября 2018

Вероятно, лучшая ставка с MySQL:

where col1 in (col2, col3, col4, . . . ) or
      col2 in (col3, col4, . . . ) or
      col3 in (col4, . . . ) or
      . . .
0 голосов
/ 10 октября 2018

NB Я понял, что ваш вопрос означает, что 2 строки считаются дубликатами, если два или более значений их столбцов равны.Если вы просто искали повторяющиеся значения в столбцах для той же строки, ответ @ 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 */
          )

ОБНОВЛЕНИЕ

Я не удивлен, что вы получаете большую разницу во времени между 1К и 130К.Я предполагаю, что масштаб будет линейным, так что 15 с * 130/1 = 1950 с, что составляет около 30 минут для запроса полной таблицы.

Также не забывайте, что для каждой строки запрос проверяет вседругие строки для дубликатов.Вот почему просто получить всю таблицу быстрее.

Я надеюсь, что вам нужно использовать этот запрос как разовый, чтобы идентифицировать дубликаты.В противном случае это указало бы на некоторую неудачную структуру базы данных и, вероятно, таблицу можно было бы реорганизовать для лучшего соответствия ее назначению.Это проблема XY, на которую @apokryfos ссылается в своем комментарии на ваш вопрос.

Приведенный выше запрос не позволит использовать какие-либо индексы для столбцов из-за сложного условия.

Вы можете потенциально быстрее достичь результата, используя UNION ALL, при условии, что у вас есть индивидуальный индекс для некоторых столбцов, а id - это PK таблицы.

  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

Может показаться здоровенным, но его легко можно динамически построить на прикладном уровне для ваших десяти и более столбцов.

Имейте в виду, что если у вас больше дубликатов, чем уникальных, это можетимеет смысл инвертировать эту логику.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...