2010-04-09 5 views
2

У меня есть несколько тысяч записей с несколькими 100 полями в таблице MySQL.Как удалить повторяющиеся записи в 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 был бы замечательным! Благодаря!

+0

Не удалось ли записать более 1 запись об ошибке для заданного значения ключа? – BenV

+0

Я думаю, что ключ на самом деле не «ключ» (возможно, серогатный ключ есть ...) – Dani

+0

Не будет более одного обмана. Они существуют парами из двух. Ключ только для того, чтобы отличить обманщиков. – ThinkCode

ответ

0
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] 

Ответа на этот вопрос Messa в this Thread ...

1

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

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

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

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

+0

Слияние звучит как план. Python может это сделать, но я новичок в Python и не уверен, как применить Python Merge к моей проблеме. Спасибо за быстрый ответ :) – ThinkCode

2

Если я правильно вас понял, что вам нужно 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 дубликат; если у вас больше, запрос необходимо изменить.

+0

Проблема в том, что существует несколько сотен столбцов. Я пытаюсь избежать неэффективной инструкции обновления для всех этих. Я надеюсь, что существует лучшее решение. Спасибо. – ThinkCode

0

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

+0

Таблица Temp не является проблемой. Единственная проблема: я не хочу обновлять все сотни столбцов вручную. – ThinkCode

+0

ok, если у вас нет временной проблемы, вы можете использовать что-то вроде этого. Вставить в tempTable (x) выберите coalesce (x1, (выберите x2 из sourceTable s2, где s2.keu = s1.key, где s2.dupe = ' x ') from sourceTable s1, где s1.dupe <>' x ' Но если у вас нет каких-либо ограничений, я рекомендую написать простой скрипт python с 2-3 запросами. –

+0

Python-скрипт очень У меня нет ограничений! Я пытаюсь придумать скрипт Python, который проходит через список обманов и несовпадений, проверяя, является ли поле нулевым ... Пожалуйста, помогите :) – ThinkCode