Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Базы";
Текущий архив: 2004.03.09;
Скачать: [xml.tar.bz2];

Вниз

Снова про удаление дублей в таблице   Найти похожие ветки 

 
Vlad   (2004-02-10 13:44) [0]

Доброго всем времени суток.
Вот тут не так давно мне посоветовали для удаления дублирующих записей в таблице использовать конструкцию вида:
delete from table t1 where
1<(select count(*) from table t2 where t2.поле1=t1.поле1 and t2.поле2=t1.поле2)

Такая конструкция обеспечивала уникальность связки полей Поле1+Поле2.
На IB запрос работал прекрасно, но вот на Oracle он удаляет не только дублирующие, но и основные записи.
Подскажите, в чем может быть дело ? Возможно ли как-то решить эту проблему с помощью настроек оптимизатора, или доп. хинтов в запросе ?


 
Johnmen   (2004-02-10 13:54) [1]

Я думаю, что дело в логике работы сервера.
Для ИБ - идет делетом по записям и каждую, удовл-ую условию, удаляет, поэтому для следующей записи селект вернет уже другое значение.
А для Оракла несколько иначе. Поскольку селект делается из модифицируемой таблицы, то, скорее всего, надо отключить "мутацию".


 
Vlad   (2004-02-10 13:58) [2]


> Johnmen © (10.02.04 13:54) [1]


> скорее всего, надо отключить "мутацию".

Спасибо. А каким образом это делается ?


 
Johnmen   (2004-02-10 14:25) [3]

>Vlad © (10.02.04 13:58)

Уже основательно это хозяйство подзабыл...:)
Думаю, что надо смотреть в эту сторону:
1. ХП
2. PRAGMA AUTONOMOUS_TRANSACTION


 
sniknik   (2004-02-10 14:46) [4]

а вроде в Oracle есть чтото вроде номера записи(?) может его както задействовать?

а вообще можно проще (по моему) и в большем количестве SQL серверов работать будет. хотя и за большее количество итераций.
select * into NewTable from (select distinct * from OldTable)
дальше надо удалить старую и переименовать новую.


 
DenK_vrtz   (2004-02-10 16:01) [5]

>Vlad ©

Если копать в сторону "мутации" (Johnmen © (10.02.04 13:54) [1]), то еще вариант к Johnmen © (10.02.04 14:25) [3] это
view и instead of триггер на удаление для этого вью

Попробуй :)


 
Vlad   (2004-02-10 16:22) [6]


> [3] Johnmen © (10.02.04 14:25)

Попробовал указать прагму, но при таком запросе в ХП Оракл вобще откатывает транзакцию с ошибкой


 
Fay   (2004-02-10 17:51) [7]

Уникальность достигается другим способом. Для этого есть UNIQUE.


 
Johnmen   (2004-02-10 17:56) [8]

>Vlad ©

К сожалению ничем конкретно не помогу...
Но общие соображения : в ХП просто делаем обход по селекту в цикле и для каждой записи отдельный делете. Т.е. "развязываем" один запрос на два... Ну и прагму "подпихнуть" :)


 
panov   (2004-02-10 18:17) [9]

Пусть T1 имеет поля Id, f1,f2, где сравнение на дубль идет по полям f1, f2 .

SELECT *
FROM
T1 a
WHERE
a.id NOT IN
(
SELECT MIN(id) mn --,f1,f2
FROM
(
SELECT a.id,a.f1,a.f2
FROM
T1 a,
(
SELECT f1,f2,cnt
FROM
(
SELECT f1,f2,COUNT(*) cnt FROM T1 GROUP BY f1,f2
) b
WHERE cnt>1
) b
WHERE a.f1=b.f1 AND a.f2=b.f2
) b
GROUP BY f1,f2
)
AND
a.id in
(
SELECT a.id
FROM
T1 a,
(
SELECT f1,f2,cnt
FROM
(
SELECT f1,f2,COUNT(*) cnt FROM T1 GROUP BY f1,f2
) b
WHERE cnt>1
) b
WHERE a.f1=b.f1 AND a.f2=b.f2
)

здесь несколько лишних алиасов, так как отлаживалось в MSSQL, но будет работать и в Oracle.
Если нет уникального Id, то вместо него можно использовать RowId.

В самом верхнем селекте зменить SELECT НА DELETE, естественно


 
panov   (2004-02-10 18:18) [10]

В строчке SELECT MIN(id) mn --,f1,f2 --,f1,f2 - комментарий, не нужен.


 
Sandman25   (2004-02-10 18:21) [11]

delete from table1
where rowid <>
(select min(rowid)
from table1 t2
where t2.field1=table1.field1
and t2.field2=table2.field2
)


 
panov   (2004-02-10 18:28) [12]

-))))


 
Sandman25   (2004-02-10 18:36) [13]

[12] panov © (10.02.04 18:28)

Вы вроде бы участвовали в sql.ipps.ru, после того конкурса такие select воспринимаются достаточно легко :)


 
Vlad   (2004-02-10 18:52) [14]

Спасибо всем кто откликнулся.

Я понимаю, что это можно сделать другими способами, но меня в данном случае интересуют не другие способы, а то, почему этот способ не проходит в Oracle и как его заставить работать. Вопрос принципа так сказать :-)
Но видимо не получится :-(


 
Sandman25   (2004-02-10 18:53) [15]

[14] Vlad © (10.02.04 18:52)

Насколько я знаю, такое проходит только для семейства IB. Во всех остальных SQL СУБД такое не проходит. Так что дело не в Oracle...



Страницы: 1 вся ветка

Форум: "Базы";
Текущий архив: 2004.03.09;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.48 MB
Время: 0.008 c
8-25831
Crite
2003-11-06 20:10
2004.03.09
MediaPlayer


6-25842
csr
2003-12-31 11:10
2004.03.09
TidSMTP и результат его работы!


1-25760
Ш-К
2004-02-26 13:51
2004.03.09
Дин. массивы.


1-25784
din
2004-02-27 10:18
2004.03.09
отчет в Excel


1-25738
-=zek=-
2004-02-26 22:03
2004.03.09
Изменение вида курсора





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский