Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.10.22;
Скачать: CL | DM;

Вниз

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

 
Ольга   (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;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.035 c
2-1160032808
АлексЧерных
2006-10-05 11:20
2006.10.22
Нужна помощь!!!


3-1155899628
Bless
2006-08-18 15:13
2006.10.22
Коды ошибок провайдера.


4-1149187609
chizra
2006-06-01 22:46
2006.10.22
У меня какая-то ошибка после установки hookа WH_CALLWNDPROC


11-1135948023
homm
2005-12-30 16:07
2006.10.22
Как получить видимый регион окна?


4-1149788245
Steplerr
2006-06-08 21:37
2006.10.22
С консолью через хендл