2014-10-16 4 views
0

. Хорошо. Поэтому я просмотрел множество тем по этому вопросу, и я попробовал много запросов, чтобы получить результат, который я хочу, так как вы Вероятно, я догадался, что до сих пор не нашел решения.MySQL Query: удалять повторяющиеся записи на основе даты, хранить самую старую запись из множества дубликатов.

У меня есть клиент, который регулярно загружает информацию в базу данных MySQL, относящуюся к счетам-фактурам. Есть 3 столбцов в таблице:

|------ 
|Column|Type|Null|Default 
|------ 
|//**invoice**//|int(11)|No|0 
|//**barcode**//|int(11)|No| 
|//**invoice_date**//|datetime|No| 

Таким образом, вы можете увидеть, есть счет-фактура, штрих-коды и invoice_date. Каждый штрих-код UNIQUE, но вы можете иметь несколько штрих-кодов, связанных с идентификатором счета-фактуры.

Теперь вы, вероятно, думаете: «Почему вы просто не добавили индекс UNIQUE на столбцы штрих-кода и invoice_date?» - У меня есть указатели на эти столбцы. Теперь вы видите, что здесь играет огромная шарик. Они используют сканер для сканирования штрих-кодов, и это затем помещается в CSV. Иногда это беспорядок, поэтому будет запись, которая ТОЧНО такая же, но ссылка invoice_date будет на пару секунд или минут, так что MySQL не будет интерпретировать это как дубликат, даже если это то же самое.

Пример обмануты записей:

|24815|86632|2008-08-21 10:22:50 
|24899|86632|2008-09-04 17:12:30 
|55555|86632|2008-08-21 10:34:41 

Так что мне нужно сделать, это:

удалить все записи КРОМЕ записи с СТАРЕЙШЕГО invoice_date, где штрих-кода является то же самое.

Таким образом из приведенных выше данных, установленных я должен был бы держать:

|24815|86632|2008-08-21 10:22:50, как тот самый старый рекорд.

Я пробовал много запросов.

например

DELETE I1 FROM v3_invoices_test I1 
LEFT JOIN 
(
    SELECT MIN(invoice_date) AS OLDESTRECORD, barcode 
    FROM v3_invoices_test 
) I2 
ON I1.barcode = I2.barcode 
WHERE OLDESTRECORD > I1.invoice_date 

DELETE FROM v3_invoices_test 
WHERE (barcode, invoice_date) IN (
    SELECT 
    barcode, 
    invoice_date 
    FROM 
     v3_invoices_test I1 
    WHERE 
    EXIST (
     SELECT * 
     FROM v3_invoices_test I2 
     WHERE I1.barcode = I2.barcode 
     AND I1.invoice_date < I2.invoice_date 
    ) 
) 

Если кто-то может помочь было бы глубоко признателен!

Благодаря

ответ

1

Вот ваша скрипка: http://sqlfiddle.com/#!2/29375b/1

Таким образом, ваш запрос будет:

DELETE FROM v3_invoices_test WHERE invoice NOT IN (
    SELECT invoice FROM (
    SELECT invoice FROM v3_invoices_test JOIN (
     SELECT barcode, MIN(invoice_date) m FROM v3_invoices_test GROUP BY barcode 
    ) temp ON t.barcode = temp.barcode AND t.invoice_date = temp.m 
) a 
); 

К сожалению, первый вложенный запрос необходим из-за # 1093 (https://stackoverflow.com/a/14302701/1767861). В основном, запрос извлекает самые старые даты, сгруппированные по штрих-коду, и применяет удаление для всех других идентификаторов.

+0

Спасибо за ответ, однако я получаю эту ошибку MySQL при запуске этого запроса: # 1054 - Неизвестный столбец «t.barcode» в разделе «on» –

+0

Отсутствие «t» после второго SELECT. Также теперь он просто замораживает мой сервер. Вероятно, следует упомянуть, что в этой таблице имеется 360 000 записей. –

+0

Да, он должен использовать довольно много ресурсов. Надеюсь, вам удалось пройти через это –

Смежные вопросы