Премахване на дублиращи се редове в SQL заявката маса

Когато има проблем с оптимизация на базата данни, или да променя своята структура, понякога задача попътен вятър на организиране на съществуващите данни. Е, ако на масата вече е в дизайна е показано в нормална форма, както и цялата система е организирана така, че да не се трупат излишно дублиране на информация. Ако това не е така, то при финализирането на такава система би било желателно да се отървете от всички излишни данни и да направи най-ефективно.

В тази статия ще обсъдим въпроса изтриване на дублиращи се редове в таблица, база данни. Веднага ще отбележа, че ние говорим за необходимостта от премахване на дублиращи се линии точно. Например, записът в таблицата на поръчки с полетата "Код за поръчка", "код на продукта", "идентификационен номер на клиента", "дата" може да варира само кода на поръчката, тъй като все още един клиент в един ден да си поръчате и същ номер артикул време. Основен показател тук, че всичко е наред - присъствието на ключовото поле.

Ако, обаче, ние виждаме една маса изобилстващи повтаря полета, без изричното необходимостта на всеки запис, това е точно това, което трябва да се поправи.

Пример ясно прекомерно таблица:

country_id (код на държавата)

city_name (площ код)

Сега нека да разгледаме по-подробно как става това. Ако поиска да се премахне, трябва да посочите състояние, което показва какъв тип данни, които искате да изтриете, и което да си тръгне. Ние не трябва да извадите уникален запис. Т.е. ако има няколко идентични записи (за които едно и също, ако те имат еднаква стойност и country_id city_name), тогава ще трябва да се вземе една от линиите, не забравяйте, кода и да изтриете всички записи с едни и същи ценности и country_id city_name, но друг код (ID).

SQL низ на заявката:

Изтриете. * FROM mytable един,

Това показва, че отпадането ще се извършва mytable маса.

След това изберете заявка генерира подкрепа на маса, където ние записи на групата, така че всички записи са уникални:

(SELECT
b.country_id, b.city_name, MIN (b.id) средата
ОТ mytable б
GROUP BY b.country_id, b.city_name
) в

MIN (b.id) средата - образува средата колона (съкращение мин Id), които са направени ID минимална стойност във всяка подгрупа.

Резултатът е таблица, която съдържа уникален идентификатор, запис и на първия ред за всяка група от дублиращи се записи.

Сега имаме две таблици. Една обща, съдържащ всички записи. Тя ще бъде отстранен от допълнителните линии. Вторият съдържа информация за линиите, които искате да запазите.

Ние можем да създадем само на условията, който гласи: трябва да се премахнат всички редове, където няма да съответстват на една и съща област и country_id city_name и идентификационен номер. В този случай, ИД избран минимална стойност, така че всички записи се изтриват, което е повече от номер, избран във временната таблица.

Трябва също да се отбележи, че по-горе операция може да се извърши в присъствието на една маса от ключово поле. Ако изведнъж се сблъска с маса без единен идентификационен код, а след това само да я добавите:

ALTER TABLE `mytable` ADD` id` INT (11) NOT NULL auto_increment. ADD първичен ключ ( `id`)

Изпълнение на такова искане, ние се получи допълнителна колона, пълна с уникална цифрова стойност за всеки ред на таблицата.

Ние извършваме всички необходими действия. След операционната маса почистване на дублирани записи се изпълнява, това поле също може да бъде премахната.

Друг материал от този раздел

Искам да обърна внимание на последната точка, ако на масата има не единен идентификационен код, той трябва да се добави, но не е задължително да го ключа, все едно след това извадете, така че "ADD основен ключ (` id`) "направи - излишно действие

Добър ден, Александър.
Наистина не е необходимо. Полето ключ се използва тук, за да осигури еднозначно уникални идентификатори. Разбираемо е, че областта на допълнителния атрибут добавите уникални кодове във възходящ ред. Но, както е описано в статията операцията, извършена в същото време, да се намали не се изисква кода. Основната задача тук - правилното изпълнение на елементите на почистване, повторете.
Благодаря ви за вашия коментар.

Направих малко по-лесно:
Изтрий от mytable КЪДЕ номер НЕ ПО (SELECT MIN (ID) ОТ mytable GROUP BY b.country_id, b.city_name);

Андрю, добър ден.
Любопитното Учих кода си. Исках да се провери на практика. Има една малка грешка (без възлагане на втората таблица, символът "В") - поправи я и се затича, както следва:

Изтрива от mytable КОИТО НЕ ПО ID (SELECT MIN (Id) ОТ mytable като В ГРУПА ОТ b.country_id, b.city_name);

Въпреки това, има грешка с препратка към върна набор от данни от вложено заявка. Ако сте имали работещ код моля, уточнете. Би било интересно да се знае по-добре искане опция.

Опитвайки се да приложите алгоритъм (мин заменя на макс - аз трябва да се остави само на последния запис). Аз използвам следния код:

Изтриете. *
ОТ Т1 като,
(SELECT б. [AF], б. [BF], макс (б. [Код]) като maxID
ОТ Т1 AS б
ГРУПА ОТ б. [AF], б. [BF]
) Като С
Когато. [AF] = С. [AF] и. [BF] = С. [BF] и. [Код]

По някаква причина той не отиде през втората половина на съобщението.
Така че, посланието при изпълнение на алгоритъма: "Не може да изтриете от определени таблици." В същото време, ако се замени за изриване на Select, извадката правилно. В това, което може да е причината за грешката?

Опитах код от Андрю:
DELETE *
ОТ T1
Код когато не IN (
SELECT макс (код)
ОТ T1
ГРУПА ОТ AF, BF);
Всичко работи перфектно. Благодаря ви много! Така предишен въпрос отива в категорията на чисто академичен. Но все пак интересно.