Понимание этого SQL-запроса - PullRequest
5 голосов
/ 21 февраля 2011

Я новичок в базе данных Oracle, может помочь мне понять этот запрос. Этот запрос удаляет дубликаты из таблицы.

DELETE FROM table_name A 
 WHERE ROWID > (SELECT min(rowid) 
                  FROM table_name B 
                 WHERE A.key_values = B.key_values);

Любые предложения по улучшению запроса приветствуются.

Редактировать : Нет, это не домашняя работа, я не понял, что делает подзапрос и что делает подзапрос ROWID > On? 1011 *

Это источник запроса

Ответы [ 4 ]

5 голосов
/ 21 февраля 2011

Рассечение фактической механики:

DELETE FROM table_name A 

Это стандартный запрос на удаление записей из таблицы с именем «table_name». Здесь это было псевдонимом «А», который будет упоминаться в подзапросе.

WHERE ROWID > 

Это накладывает условие на удаление, так что для каждой встреченной строки ROWID должен соответствовать условию, превышающему ..

            (SELECT min(rowid) 
              FROM table_name B 
             WHERE A.key_values = B.key_values)

Это подзапрос, который связан с основным оператором DELETE. Он использует значение A.key_values из внешнего запроса. Поэтому, учитывая запись из оператора DELETE, он выполнит этот подзапрос, чтобы найти минимальный идентификатор строки (внутренний идентификатор записи) для всех записей в одной таблице (теперь с псевдонимом B), которые имеют одинаковое значение key_values.

Итак, чтобы сложить это, скажем, у вас были эти строки

rowid   |  key_values
=======    ============
1          A
2          B
3          B
4          C
5          A
6          B

В подзапросе выясняется, что min (rowid) для каждой записи на основе ВСЕХ записей с одинаковым key_values равно:

rowid   |  key_values    | min(rowid)
=======    ============    ===========
1          A               1
2          B               2
3          B               2  **
4          C               4
5          A               1  **
6          B               2  **

Для записей, помеченных **, условие

WHERE ROWID > { subquery }

становится истинным, и они удаляются.

РЕДАКТИРОВАТЬ - дополнительная информация

В этом ответе ранее говорилось, что ROWID увеличивается на порядок вставки. Это очень не соответствует действительности. Правда в том, что rowid is just a file.block.slot-on-block - a physical address.

http://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_ID:53140678334596

Tom's Продолжение 1 декабря 2008 г. - 6:00 Центральный часовой пояс:

вполне возможно, что D будет "первым" в таблице - так как он занял место А.

Если бы rowids всегда «рос», то пространство никогда бы не использовалось повторно (это было бы следствием растущего всегда rowids - мы никогда не смогли бы повторно использовать старое пространство, так как rowid - это просто file.block.slot-on- блок - физический адрес)

3 голосов
/ 21 февраля 2011

Rowid - псевдостолбец, который уникально идентифицирует каждую строку в таблице;это число.

Этот запрос находит все строки в A где A.key_values = B.key_values и удаляет все из них, кроме одной с минимальным значением rowid.Это просто способ произвольно выбрать один дубликат для сохранения.

3 голосов
/ 21 февраля 2011

Цитата AskTom :

Идентификатор строки присваивается строке при вставке и является неизменным (никогда не изменяется) ... если строка не удалена и не вставлена ​​повторно (это означает, что это другая строка, а не та же!)

Ваш запрос основан на этом rowid и удаляет все строки со значением rowid, превышающим минимальное значение для каждого key_values основа.Следовательно, все дубликаты удаляются.

Предоставленный вами подзапрос является коррелированным подзапросом, поскольку существует связь между ссылкой на таблицу в подзапросе и одной ссылкой вне подзапроса.

1 голос
/ 21 февраля 2011

ROWID - это число, которое увеличивается для каждой новой вставленной строки. Таким образом, если у вас есть два ROWID числа 16 и 24, вы знаете, что 16 было вставлено до 24. Ваш оператор delete удаляет все дубликаты, сохраняя только первый из этих дубликатов, который был вставлен. Есть смысл ??

...