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

Вниз

Удаление данных из таблицы с подзапросом   Найти похожие ветки 

 
Ольга   (2006-08-21 17:42) [0]

Не могу составить правильный запрос на удаление. Делаю выборку данных, которые хочу удалить:

SELECT * FROM T1 a
WHERE NOT EXISTS (select id1, id2 from T2 b where  a.id1=b.id1 and a.id2=b.id2)

Выбирается, то, что надо. Беру подзапрос в скобки, добавляю в начало:

DELETE FROM T1 WHERE EXISTS (подзапрос)

Получаю полное удаление всех записей.
Делаю какую-то глупость и не вижу где. Помогайте, мастера.


 
clickmaker ©   (2006-08-21 17:49) [1]

DELETE FROM T1 WHERE id1 IN (SELECT Id1 from T2 ...)


 
Ega23 ©   (2006-08-21 17:49) [2]


> DELETE FROM T1 WHERE EXISTS (подзапрос)


Exists - что возвращает?  :о)


 
Ольга   (2006-08-21 18:17) [3]


> [2]

Где глупость поняла, спасибо.

> [1]

Да, так работает. Только конструкция получается громоздкая:

DELETE FROM T1
WHERE id1 IN
(
SELECT DISTINCT id1
FROM T1 a
WHERE NOT EXISTS (select id1 from T2 b where  a.id1=b.id1 and a.id2=b.id2)
)
AND id2 IN
(SELECT DISTINCT id2
FROM T1 a
WHERE NOT EXISTS (select id2 from T2 b where  a.id1=b.id1 and a.id2=b.id2)
)

Запрос строится динамически на произвольной таблице - удаление данных, не соответсвующих условиям внешнего ключа.
Можно как-то упростить этот запрос (а то программа становится не читабельной)?


 
Dok   (2006-08-21 18:43) [4]


> DELETE FROM T1 WHERE id1 IN (SELECT Id1 from T2 ...)

не очень гуд на больших выборках. всегда почти можно заменить на exists


 
Dok   (2006-08-21 18:44) [5]

delete FROM T1
WHERE NOT EXISTS (select * from T2 b where  T1.id1=b.id1 and T1.id2=b.id2)


 
Ольга   (2006-08-21 19:03) [6]

[5]
О, так значительно лучше. Где-то в подсознании (до сознания без помощи, к сожалению, не дошло) я именно это и хотела получить.
Спасибо!


 
Anatoly Podgoretsky ©   (2006-08-21 19:05) [7]

Это два разных по результату запроса

SELECT * FROM T1 a
WHERE NOT EXISTS (select id1, id2 from T2 b where  a.id1=b.id1 and a.id2=b.id2)

Выбирается, то, что надо. Беру подзапрос в скобки, добавляю в начало:

DELETE FROM T1 WHERE EXISTS (подзапрос)


 
Fay ©   (2006-08-21 19:06) [8]

delete T1
from T1 left join T2 on T1.ID1 = T2.ID1 and T1.ID2 = T2.ID2
where T1.FirstKeyField is null


 
Ольга   (2006-08-22 06:46) [9]


> where T1.FirstKeyField is null

Это условие зачем? И что за зверь FirstKeyField?


 
sniknik ©   (2006-08-22 09:01) [10]

> Это условие зачем?
отбирает для удаления только "неподсоеденившиеся концы" в обьеденении, т.е. по смыслу - то чего нет в другой таблице (NOT EXISTS по смыслу).

> И что за зверь FirstKeyField?
дикий...

т.к. в вопросе не приведена структура таблиц/используемые поля (но из запросов ясно что id1, id2 скорее всего не ключевые, иначе хватило бы одного сравнения), то тебе дали свой вариант, придуманное/собственное название поля, что за поле это ясно из его названия...


 
Ольга   (2006-08-22 09:31) [11]

Можно еще раз пояснить (для "особо сообразительных").
Подробнее:
Т1 - некая таблица, на которую планируется наложить внешний ключ
      Т1.id1, Т1.id2 - поля, соответствующие первичному ключу внешней таблицы
Т2 - внешняя таблица
      Т2.id1, Т2.id2 - первичный ключ
В полях Т1.id1, Т1.id2 может попасться null, как частный случай.
В данных условиях я могу обойтись без этого where или я чего-то недопоняла?


 
Dok   (2006-08-22 10:03) [12]


> from T1 left join T2 on T1.ID1 = T2.ID1 and T1.ID2 = T2.
> ID2

left outer join будет медленее чем exists


 
Dok   (2006-08-22 10:07) [13]


> В данных условиях я могу обойтись без этого where или я
> чего-то недопоняла?

не можете, так как левое соединение даст null для тех записей которых нет в T1, что Вам и требовалось.


 
Ольга   (2006-08-22 10:14) [14]

Разобралась что почем.
Всем спасибо!


 
Dok   (2006-08-22 10:55) [15]


> не можете, так как левое соединение даст null для тех записей
> которых нет в T1, что Вам и требовалось.

вообще-то тут нужно правое соединение


 
Fay ©   (2006-08-22 17:21) [16]

Dok   (22.08.06 10:55) [15]
Почему правое?


 
Dok   (2006-08-22 18:43) [17]

потому что нужно выбрать те которых нет в T2


 
Fay ©   (2006-08-22 19:45) [18]

Dok   (22.08.06 18:43) [17]
> потому что нужно выбрать те которых нет в T2
На самом деле, ошибка в where T1.FirstKeyField is null - должно быть where T2.FirstKeyField is null

P.S.
> left outer join будет медленее чем exists
Сравни планы.


 
Dok   (2006-08-23 10:40) [19]


> На самом деле, ошибка в where T1.FirstKeyField is null -
>  должно быть where T2.FirstKeyField is null

ну правильно. или правое соединение:)

> > left outer join будет медленее чем exists
> Сравни планы.

Только что проверил на 80 тыс. в T1 и 600 тыс в T2 Выиграл exists. Это и понятно судя из того как работает внешнее соединение и как exists.
Индексы по полям соединения есть.



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

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

Наверх





Память: 0.48 MB
Время: 0.205 c
4-1149705903
Sam Stone
2006-06-07 22:45
2006.10.22
Планировщик заданий


2-1159976527
ArtemESC
2006-10-04 19:42
2006.10.22
МНОГА указателей...


4-1149856535
TRyaSS
2006-06-09 16:35
2006.10.22
Как открыть существующий файл, чтобы дописать с


15-1159463241
Layner
2006-09-28 21:07
2006.10.22
Расчет полиноминального тренда 6й степени


2-1159794603
Fantasy
2006-10-02 17:10
2006.10.22
IBDataSet1BeforePost





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский