Как удалить дубликаты записей в MySQL, сохранив эти поля с данными в дубликате, но не в исходном элементе? - PullRequest
2 голосов
/ 09 апреля 2010

У меня есть несколько тысяч записей с несколькими 100 полями в таблице MySQL.

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

Например:

a b c d e f key dupe
--------------------
1 d c f k l 1   x
2 g   h   j 1    
3 i   h u u 2
4 u r     t 2   x

Из приведенной выше таблицы примеров, желаемый результат:

a b c d e f key dupe
--------------------
2 g c h k j 1
3 i r h u u 2

Если вы внимательно посмотрите, дубликат определяется с помощью ключа (он одинаков для 2 записей, поэтому тот, который имеет «x» для поля дублирования, удаляется при сохранении некоторых поля из дубли (например, значения c, e для ключа 1).

Пожалуйста, дайте мне знать, если вам нужна дополнительная информация об этой загадочной проблеме.

Спасибо за тонну!

p.s: Если невозможно использовать MySQL, пример сценария PERL / Python будет потрясающим! Спасибо!

Ответы [ 4 ]

2 голосов
/ 09 апреля 2010

Если я вас правильно понял, вам нужно 1) объединить 2 записи 2) удалить отмеченные записи (это просто).

Для выполнения первой задачи вы можете использовать что-то вроде

UPDATE table1 t1 
INNER JOIN table1 t2 ON (t1.key = t2.key AND t2.dupe='x')
SET t1.b= IFNULL(t1.b,t2.b), t1.c=IFNULL(t1.c,t2.c), ...etc
WHERE t1.dupe IS NULL

P.S. Этот запрос предполагает, что любая запись имеет 0 или 1 дубликат; если у вас есть больше, запрос необходимо изменить.

1 голос
/ 09 апреля 2010

Используя код, вы можете объединить строки, а затем удалить дубликаты.

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

итерация по всем парам дупсов с использованием какого-либо курсора.

Это общая идея, я надеюсь, что кто-то здесь может помочь вам с более конкретным кодом ...

0 голосов
/ 12 апреля 2010
import string, os, sys
import csv
import MySQLdb
import pickle
from EncryptedFile import EncryptedFile

enc = EncryptedFile( os.getenv("HOME") + '/.py-encrypted-file')
user = enc.getValue("user")
pw = enc.getValue("pw")

db = MySQLdb.connect(host="127.0.0.1", user=user, passwd=pw,db=user)

cursor = db.cursor()
cursor2 = db.cursor()

cursor.execute("select * from delThisTable")
rows = cursor.fetchall()
data = dict()
for row in rows:
    key, primary = row[0], row[1]
    if key not in data:
        data[key] = list(row[:-1])
    else:
        for i in range(len(row)-1):
            if data[key][i] is None or (not primary and row[i] is not None):
                data[key][i] = row[i]

Ответ Мессы в этой теме ...

0 голосов
/ 09 апреля 2010

Ответ очень зависит от того, что вы действительно хотите сделать. Вы хотите редактировать дубликаты записей на месте, или вы хотите создать временную таблицу с желаемым результатом. Если вы хотите редактировать записи на месте, я думаю, что вам лучше использовать python для выполнения нескольких последовательных запросов, например, a1ex07 скажем, а затем просто «удалить из ..., где dupe =« x »». Если вы можете использовать временную таблицу, вы можете использовать одну (не очень) простую mysql 'INSERT INTO ... SELECT', объединяя записи дублирования с IFNULL или CAOLESCE и действительные записи игоноринга с помощью dupe = 'x'

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