Как удалить в MS Access при использовании JOIN?

Я пытаюсь использовать предложение DELETE в MS Access, и у меня возникла проблема при использовании предложения JOIN. Я заметил, что этого можно добиться с помощью ключевого слова DISTINCTROW.

Например, следующий оператор SQL не допускает удаления:

DELETE Table1.*
FROM Table1 INNER JOIN Table2 ON Table1.Name=Table2.Name;

Однако это утверждение:

DELETE DISTINCTROW Table1.*
FROM Table1 INNER JOIN Table2 ON Table1.Name=Table2.Name;
  • Почему DELETE работает при использовании ключевого слова DISTINCTROW?
  • В частности, что происходит в двигателе JET, чтобы этого потребовать?

person Curtis Inderwiesche    schedule 07.04.2011    source источник
comment
Учитывая, что DELETE работает с целыми строками, а не со столбцами, указывать что-нибудь между ключевыми словами DELETE и FROM не имеет смысла.   -  person onedaywhen    schedule 11.04.2011


Ответы (3)


Delete Table1.*
From Table1
Where Exists( Select 1 From Table2 Where Table2.Name = Table1.Name ) = True

Чтобы расширить мой ответ, официальная спецификация SQL не предусматривает использование соединений в запросах действия специально потому, что это может создавать неоднозначные результаты. Таким образом, будет лучше (и Access будет намного счастливее), если вы сможете избежать использования объединений в запросах действий, как я здесь. Причина, по которой Access хочет DISTINCTROW, заключается в том, что вполне вероятно, что соединение между двумя таблицами создаст дубликаты строк Table1 (т. Е. В Table2 есть несколько связанных строк), и, таким образом, Access запутается. Я также обнаружил, что если вы попытаетесь использовать присоединение, а первичный ключ не существует, Access откажется. В общем, по возможности лучше избегать соединения в запросе действия.

person Thomas    schedule 07.04.2011
comment
Ваш ответ совершенно правильный - вся цель DISTINCTROW состоит в том, чтобы преобразовать мультитаблицу в уникальные строки таким образом, чтобы сделать их редактируемыми. - person David-W-Fenton; 10.04.2011
comment
Я хотел бы добавить, что приведенный выше запрос может иметь крайне низкую производительность при использовании соединений с перекрестной базой данных (или доступа к другой базе данных), чего не происходит с DISTINCTROW. (в одном случае это было 20 секунд, а не закончилось через 1 час) - person Stefan; 04.09.2012
comment
@Stefan - альтернативной версией того же запроса будет Where PKCol In(...) = True, который устраняет корреляцию и даже в сценариях с несколькими базами данных должен работать хорошо. Поскольку в Access нет возможности анализировать план выполнения, нет возможности легко определить, что DISTINCTROW действительно делает и что делает плохо при использовании функции Exists. Нам остается использовать метод проб и ошибок. - person Thomas; 05.09.2012
comment
Этот запрос можно упростить, удалив избыточное сравнение «= True». - person Mariusz Bialobrzeski; 23.01.2018
comment
Теоретически ... да. Однако я, кажется, помню старые версии Access, в которых фактически требовалось явное сравнение с логической константой. - person Thomas; 24.01.2018
comment
Работал как шарм. (Я всегда зацикливаюсь на кажущихся простыми задачах.) Я часто забываю, что Access разрешил использование подзапросов в окне Query Design. - person ashleedawg; 27.03.2018

Следует помнить об одной проблеме: это НЕ работает с псевдонимами таблиц / запросов!

DELETE a.*
from tblA as A
where exists (select 1 from tblB as B where a.id=b.id)

Удаляет ВСЕ записи в tblA! Я пробовал использовать псевдонимы для tblA и tblB по отдельности - результат тот же (Access 2010).

Бывает и с SELECT (который я часто использую перед удалением) ...

person MarcusFey    schedule 03.06.2014

DELETE a.*
FROM tblA AS A
WHERE EXISTS (SELECT 1 FROM tblB AS B WHERE a.id=b.id)

попробуй это

DELETE tblA 
FROM tblB  
WHERE EXISTS (SELECT * FROM tblA AS A,tblB AS B WHERE A.id=B.id)
person user7047561    schedule 20.10.2016
comment
Удалить из таблицы, где идентификатор в (выберите идентификатор из таблицы) - person user7047561; 20.10.2016
comment
для объединенного стола: - person user7047561; 21.10.2016
comment
УДАЛИТЬ * ИЗ ttrans ГДЕ существует (выберите a. * Из ttrans a, temp_tmbtrans b, где ttrans.ref_code = b.ref_code и ttrans.fund_account = b.fund_account и ttrans.tr_date = b.tr_date и ttrans.tr_code = b.tr_date и ttrans.tr_code = b.tr_date and ttrans.tr_code = b.tr_date and ttrans.tr_code = b.tr_date and ttrans.tr_code = b.tr_date and ttrans.tr_code = ttrans.sharecode = b.sharecode и ttrans.unit = b.unit и ttrans.amt = b.amt и ttrans.price = b.price и ttrans.account = b.account); - person user7047561; 21.10.2016
comment
В ответ на комментарий выше имейте в виду, что MS Access не поддерживает временные таблицы. - person Dai; 23.12.2020