Форум: "Базы";
Текущий архив: 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