Как выбрать и / или удалить все, кроме одной строки каждого набора дубликатов в таблице?

Допустим, у меня есть таблица MySQL с четырьмя столбцами:

ID DRIVER_ID CAR_ID ПРИМЕЧАНИЯ (NULL для большинства строк)

У меня есть несколько повторяющихся строк, в которых DRIVER_ID и CAR_ID совпадают. Для каждой пары DRIVER_ID и CAR_ID мне нужна одна строка. Если одна из строк в наборе содержит ЗАМЕТКИ, отличные от NULL, я хочу эту, но в остальном это не имеет значения.

поэтому, если у меня есть:

ID  |  DRIVER_ID  |  CAR_ID  |  NOTES
1      1             1          NULL
2      1             1          NULL
3      1             2          NULL
4      1             2          NULL
5      2             3          NULL
6      2             3          NULL
7      2             3          NULL
8      2             3          hi
9      3             5          NULL

, я хочу сохранить следующие идентификаторы: 9, 8, а затем по одному из [3,4] и [1,2].

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

(И да, я знаю, как обстоят дела с составными ключами. Это не проблема.)

РЕДАКТИРОВАТЬ: Извините, забыл указать, что это был MySQL.

Некоторые из того, что я пробовал до сих пор:

select ID, COUNT(DRIVER_ID) rowcount from CARS_DRIVERS group by CAR_ID,DRIVER_ID HAVING rowcount > 1;

даст мне один идентификатор на группу.Однако не обязательно оставлять строку с ЗАМЕТКАМИ, если она есть. Это также даст мне только один идентификатор для каждой повторяющейся группы. В некоторых случаях существует более 20 повторяющихся комбинаций, поэтому мне придется повторять это снова и снова, чтобы свести каждую группу к одной строке.

select distinct t1.ID from CARS_DRIVERS t1 where exists (select * from CARS_DRIVERS t2 where t2.CAR_ID = t1.CAR_ID and t2.DRIVER_ID = t1.DRIVER_ID and t2.id > t1.id);

Это намного медленнее и все еще не решает проблему NOTES . У него есть преимущество в получении самой старой строки для каждой группы, которая, если я не могу легко выделить поле NOTES, может быть прокси для этого. Если в строке в наборе есть ЗАМЕЧАНИЯ, я считаю, что это всегда самая старая строка (с наименьшим идентификатором), но я не уверен.

Дополнительный контекст: DRIVER_ID и CAR_ID не являются настоящими именами столбцов, и там другие столбцы в таблице. Я пытался выделить информацию, чтобы разобраться в корне проблемы, но из комментария W4M я вижу, что это выглядит как домашнее задание. Реальная проблема заключается в том, что я смотрю на очень неоптимизированную базу данных (обычно не в мою компетенцию), и когда я пытаюсь избавиться от этих дубликатов перед добавлением ключа, операция занимает вечность. Как в часах. Стол большой, но, конечно, этого не оправдывает. Я пытаюсь использовать свои ограниченные знания SQL и найти способ сделать это. Неважно, красиво ли, я могу сесть в командную строку и при необходимости перебрать кучу запросов. Но я заметил, что ВЫБОР идентификаторов, которые являются кандидатами на удаление, занимает всего несколько секунд, и, хотя таблица огромна, общее количество удаляемых строк меньше 10 КБ, поэтому должен быть способ сделать это без какого-либо сценария, который требует целые выходные до конца.

7
задан NChase 24 June 2011 в 19:52
поделиться