Как удалить дублирующиеся записи в mysql базе данных?

Если вы ищете способ его достижения без использования внешней библиотеки, вам поможет следующий код.

public static Map<String, String> splitQuery(URL url) throws UnsupportedEncodingException {
    Map<String, String> query_pairs = new LinkedHashMap<String, String>();
    String query = url.getQuery();
    String[] pairs = query.split("&");
    for (String pair : pairs) {
        int idx = pair.indexOf("=");
        query_pairs.put(URLDecoder.decode(pair.substring(0, idx), "UTF-8"), URLDecoder.decode(pair.substring(idx + 1), "UTF-8"));
    }
    return query_pairs;
}

Вы можете получить доступ к возвращенной карте с помощью <map>.get("client_id"), с URL-адресом заданный в вашем вопросе, это вернет «SS».

UPDATE URL-декодирование добавлено

UPDATE. Поскольку этот ответ все еще довольно популярен, я сделал улучшенную версию вышеописанного метода, который

public static Map<String, List<String>> splitQuery(URL url) throws UnsupportedEncodingException {
  final Map<String, List<String>> query_pairs = new LinkedHashMap<String, List<String>>();
  final String[] pairs = url.getQuery().split("&");
  for (String pair : pairs) {
    final int idx = pair.indexOf("=");
    final String key = idx > 0 ? URLDecoder.decode(pair.substring(0, idx), "UTF-8") : pair;
    if (!query_pairs.containsKey(key)) {
      query_pairs.put(key, new LinkedList<String>());
    }
    final String value = idx > 0 && pair.length() > idx + 1 ? URLDecoder.decode(pair.substring(idx + 1), "UTF-8") : null;
    query_pairs.get(key).add(value);
  }
  return query_pairs;
}

UPDATE Версия Java8

public Map<String, List<String>> splitQuery(URL url) {
    if (Strings.isNullOrEmpty(url.getQuery())) {
        return Collections.emptyMap();
    }
    return Arrays.stream(url.getQuery().split("&"))
            .map(this::splitQueryParameter)
            .collect(Collectors.groupingBy(SimpleImmutableEntry::getKey, LinkedHashMap::new, mapping(Map.Entry::getValue, toList())));
}

public SimpleImmutableEntry<String, String> splitQueryParameter(String it) {
    final int idx = it.indexOf("=");
    final String key = idx > 0 ? it.substring(0, idx) : it;
    final String value = idx > 0 && it.length() > idx + 1 ? it.substring(idx + 1) : null;
    return new SimpleImmutableEntry<>(key, value);
}

Выполнение вышеуказанного метода с помощью URL

https://stackoverflow.com?param1=value1&param2=&param3=value3&param3

возвращает эту карту:

{param1=["value1"], param2=[null], param3=["value3", null]}
13
задан nan 18 March 2009 в 20:12
поделиться

8 ответов

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

 select distinct * into NewTable from MyTable
10
ответ дан 1 December 2019 в 19:08
поделиться

Можно использовать:

http://lenniedevilliers.blogspot.com/2008/10/weekly-code-find-duplicates-in-sql.html

, чтобы получить дубликаты и затем просто удалить их через код Ruby или код SQL (я сделал бы это в коде SQL, но это ваше дело:-)

0
ответ дан 1 December 2019 в 19:08
поделиться

В новинку для SQL:-) Это - классический вопрос - часто спрашиваемый в interviews:-), я не знаю, будет ли он работать в MySQL, но он работает в большинстве баз данных -

> create table t(
>     a char(2),
>     b char(2),
>     c smallint )

> select a,b,c,count(*) from t
> group by a,b,c
> having count(*) > 1
a  b  c
-- -- ------ -----------
(0 rows affected)

> insert into t values ("aa","bb",1)
(1 row affected)

> insert into t values ("aa","bb",1)
(1 row affected)

> insert into t values ("aa","bc",1)
(1 row affected)

> select a,b,c,count(*) from t group by a,b,c having count(*) > 1
a  b  c 
-- -- ------ -----------
aa bb      1           2
(1 row affected)
4
ответ дан 1 December 2019 в 19:08
поделиться

хорошо, если это - маленькая таблица, от консоли направляющих можно сделать

class ActiveRecord::Base
  def non_id_attributes
    atts = self.attributes
    atts.delete('id')
    atts
  end
end

duplicate_groups = YourClass.find(:all).group_by { |element| element.non_id_attributes }.select{ |gr| gr.last.size > 1 }
redundant_elements = duplicate_groups.map { |group| group.last - [group.last.first] }.flatten
redundant_elements.each(&:destroy)
7
ответ дан 1 December 2019 в 19:08
поделиться

Я имел к , недавно делают это на Oracle, но шаги были бы тем же на MySQL. Это было много данных, по крайней мере, по сравнению с тем, с чем я привык работать, таким образом, мой процесс к de-dup был сравнительно тяжеловесом. Я включаю его здесь в случае, если кто-то еще приезжает с подобной проблемой.

Мои дублирующиеся записи имели различные идентификаторы, отличающиеся updated_at времена, возможно отличающиеся updated_by идентификаторы, но все другие столбцы то же. Я хотел сохранить последний раз обновленным из любого дублирующегося набора.

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

Шаг один: выполняет сценарий граблей для идентификации идентификаторов дублирующихся записей, с помощью образцовой логики. Идентификаторы входят в текстовый файл.

Шаг два: составляют временную таблицу с одним столбцом, идентификаторы для удаления, загруженный из текстового файла.

Шаг три: составляют другую временную таблицу со всеми записями, которые я собираюсь удалить (на всякий случай!).

CREATE TABLE temp_duplicate_models 
  AS (SELECT * FROM models 
  WHERE id IN (SELECT * FROM temp_duplicate_ids));

Шаг четыре: фактическое удаление.

DELETE FROM models WHERE id IN (SELECT * FROM temp_duplicate_ids);
0
ответ дан 1 December 2019 в 19:08
поделиться

Вот еще одна идея на определенном языке:

rs = `select a, b, count(*) as c from entries group by 1, 2 having c > 1`
rs.each do |a, b, c|
  `delete from entries where a=#{a} and b=#{b} limit #{c - 1}`
end

Редактировать:

Слава Олафу за эту подсказку:)

8
ответ дан 1 December 2019 в 19:08
поделиться

Если ваша таблица имеет PK (или вы можете легко задать его), вы можете указать любое количество столбцов в таблице, чтобы они были равны (чтобы квалифицировать это как дубликат) с помощью следующего запроса (может выглядеть немного грязно, но это работает):

DELETE FROM table WHERE pk_id IN(
   SELECT DISTINCT t3.pk_id FROM (
       SELECT t1.* FROM table AS t1 INNER JOIN (
           SELECT col1, col2, col3, col4, COUNT(*) FROM table
           GROUP BY col1, col2, col3, col4 HAVING COUNT(*)>1) AS t2
       ON t1.col1 = t2.col1 AND t1.col2 = t2.col2 AND t1.col3 = t2.col3 AND
       t1.col4 = t2.col4)
   AS t3, (
       SELECT t1.* FROM table AS t1 INNER JOIN (
           SELECT col1, col2, col3, col4, COUNT(*) FROM table
           GROUP BY col1, col2, col3, col4 HAVING COUNT(*)>1) AS t2
       ON t1.col1 = t2.col1 AND t1.col2 = t2.col2 AND t1.col3 = t2.col3 AND
       t1.col4 = t2.col4)
   AS t4
   WHERE t3.col1 = t4.col1 AND t3.pk_id > t4.pk_id

)

Это оставит первую запись, введенную в базу данных, удалив "самые новые" дубликаты. Если вы хотите оставить последнюю запись, поменяйте > на <.

.
0
ответ дан 1 December 2019 в 19:08
поделиться

В MySql, когда я помещал что-то вроде

delete from A where IDA in (select IDA from A )

mySql сказал что-то вроде «вы не можете использовать ту же таблицу в части выбора операции удаления».

Я просто пришлось удалить несколько повторяющихся записей, и мне удалось с помощью такой программы .php

<?php
...
$res = hacer_sql("SELECT MIN(IDESTUDIANTE) as IDTODELETE 
FROM `estudiante` group by `LASTNAME`,`FIRSTNAME`,`CI`,`PHONE`
HAVING COUNT(*) > 1 )");
while ( $reg = mysql_fetch_assoc($res) ) {
   hacer_sql("delete from estudiante where IDESTUDIANTE = {$reg['IDTODELETE']}");
}
?>
0
ответ дан 1 December 2019 в 19:08
поделиться
Другие вопросы по тегам:

Похожие вопросы: