Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Oracle Tutorial.docx
Скачиваний:
0
Добавлен:
24.01.2020
Размер:
401.64 Кб
Скачать

Задача. Удаление дубликатов.

Есть таблица KK_STUDENTS с единственным полем NAME - именами студентов.

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

Создадим таблицу:

CREATE TABLE KK_STUDENTS

(

NAME varchar(50)

);

Заполним ее данными:

insert into KK_STUDENTS(NAME) values('Алексей');

insert into KK_STUDENTS(NAME) values('Сергей');

insert into KK_STUDENTS(NAME) values('Иван');

insert into KK_STUDENTS(NAME) values('Андрей');

insert into KK_STUDENTS(NAME) values('Иван');

insert into KK_STUDENTS(NAME) values('Алексей');

insert into KK_STUDENTS(NAME) values('Пётр');

insert into KK_STUDENTS(NAME) values('Алексей');

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

Посмотрим, какие записи вставились в таблицу:

select rowid, name from kk_students;

Вот эти записи мы оставим, а остальные удалим:

select name, min(rowid) from kk_students group by name;

Приведем delete, решающий задачу:

delete from kk_students

where rowid not in (select min(rowid) from kk_students group by name);

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

Задача. Удаление по условию not in.

Создать таблицу KK_XX c данными

NAME

DT

VAL

Красный

07.08.2011

123

Красный

17.11.2011

513425

Красный

19.02.2012

3245

Cиний

07.08.2011

879

Cиний

07.08.2011

932

Зеленый

07.08.2011

89123

Зеленый

05.09.2011

89210

Зеленый

05.09.2011

6365

Написать один оператор DELETE, который оставит для каждого NAME только записи с максимальным DT, а более ранние записи удалит.

Создадим таблицу и заполним ее данными:

create table KK_XX(name varchar2(30), dt date, val number);

insert into KK_XX(name, dt, val) values('Красный', to_date('07.08.2011','dd.mm.yyyy'), 123);

insert into KK_XX(name, dt, val) values('Красный', to_date('17.11.2011','dd.mm.yyyy'), 513425);

insert into KK_XX(name, dt, val) values('Красный', to_date('19.02.2012','dd.mm.yyyy'), 3245);

insert into KK_XX(name, dt, val) values('Cиний', to_date('07.08.2011','dd.mm.yyyy'), 879);

insert into KK_XX(name, dt, val) values('Cиний', to_date('07.08.2011','dd.mm.yyyy'), 932);

insert into KK_XX(name, dt, val) values('Зеленый', to_date('07.08.2011','dd.mm.yyyy'), 89123);

insert into KK_XX(name, dt, val) values('Зеленый', to_date('05.09.2011','dd.mm.yyyy'), 89210);

insert into KK_XX(name, dt, val) values('Зеленый', to_date('05.09.2011','dd.mm.yyyy'), 6365);

Проведем удаление:

DELETE FROM KK_XX

WHERE (NAME, DT) NOT IN (SELECT NAME, MAX(DT) FROM KK_XX GROUP BY NAME);

Проверим результат:

select * from KK_XX;

Замена exists/not exists на left join + rowid.

Создадим таблицу - справочник цветов - и заполним ее данными (поле NAME - уникально):

create table KK_COLORS(name varchar2(30));

insert into KK_COLORS(name) values ('Серый');

insert into KK_COLORS(name) values ('Зеленый');

insert into KK_COLORS(name) values ('Красный');

insert into KK_COLORS(name) values ('Черный');

Тогда запрос с "exists"

select KK_XX.*

from KK_XX

where exists (select 1 from KK_COLORS where KK_XX.NAME = KK_COLORS.NAME);

можно переписать на запрос с "left join" и "rowid is not null"

select KK_XX.*

from KK_XX

left join KK_COLORS

on KK_XX.NAME = KK_COLORS.NAME

where KK_COLORS.rowid is not null;

А запрос с "not exists"

select KK_XX.*

from KK_XX

where not exists (select 1 from KK_COLORS where KK_XX.NAME = KK_COLORS.NAME);

можно переписать на запрос с "left join" и "rowid is null"

select KK_XX.*

from KK_XX

left join KK_COLORS

on KK_XX.NAME = KK_COLORS.NAME

where KK_COLORS.rowid is null;

Способы с "left join" и "rowid" зачастую работают быстрее, поэтому на практике стоит пробовать их использование.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]