Как удалить строки из одной таблицы, которые ранее принадлежали другой таблице? - PullRequest
0 голосов
/ 12 марта 2020

Table1 имеет:

  • Column1a,
  • Column2a и
  • Column3a

Table2 имеет:

  • Column1b,
  • Column2b и
  • Column3b

Я ищу отменить следующую SQL инструкцию:

INSERT INTO Table1(Column1a, Column2a, Column3a) 
SELECT Column1b, Column2b, Column3b FROM Table2

Вставляет данные Column1b, Column2b, Column3b из таблицы 2 в таблицу 1 в столбцы Column1a, Column2a, Column3a. Я хочу иметь возможность удалить эти недавно вставленные записи из таблицы 1. Что я пробовал:

DELETE FROM Table1 WHERE EXISTS ( SELECT * FROM Table2)

Этот оператор должен удалить все строки из таблицы Table1, которые также существовали в таблице Table2. Вместо этого это удалило все строки из Table1. Я что-то упускаю?

Ответы [ 3 ]

0 голосов
/ 12 марта 2020

DELETE FROM Table1 WHERE EXISTS ( SELECT * FROM Table2) говорит об удалении строки, если exists(SELECT * FROM Table2) имеет значение true. Если в таблице 2 есть какие-либо строки, это будет истина, и все строки будут удалены.

Вместо этого необходимо указать, какие столбцы в таблице1 должны совпадать с какими столбцами таблицы2. Это должны быть все столбцы, которые вы использовали при вставке / выборе в коррелированном подзапросе .

delete from table1
where exists(
  select 1 from table2
  where table1.column1a = table2.column1b
    and table1.column2a = table2.column2b
    and table1.column3a = table2.column3b
)

. Это не приведет к отмене вставки / выбора со 100% точностью. table1 и table2, возможно, изменились. В таблице table1 могут быть строки, которые соответствуют строкам таблицы table2, но не были добавлены вашей вставкой / выбором.

Если у вас есть столбец метки времени, в котором указано время создания строки, вы также можете использовать его для избегайте удаления строк, которые просто совпадают с шаблоном.

delete from table1
where exists(
  select 1 from table2
  where table1.column1a = table2.column1b
    and table1.column2a = table2.column2b
    and table1.column3a = table2.column3b
) and
created_at >= [time when you did the insert]

Попробуйте .

Вы также можете определить диапазон rowids которые были затронуты и используют это. Например, если вы определите, что строки с 50 по 100 были добавлены вашей вставкой / выбором ...

delete from table1
where rowid between 50 and 100

Конечно, сделайте это в транзакции, чтобы вы могли выполнить откат в случае ошибки.

0 голосов
/ 12 марта 2020

Если ваша версия SQLite 3.15.0+, вы можете использовать ROW VALUES в выражении DELETE, например:

DELETE FROM Table1 
WHERE (Column1a, Column2a, Column3a) IN (
  SELECT Column1b, Column2b, Column3b
  FROM Table2
)
0 голосов
/ 12 марта 2020

Ваш запрос на удаление эффективно работает следующим образом.

Выберите все данные в таблице2. Продукт присоединяется к каждой строке в таблице1. Если какие-либо записи соответствуют записи в таблице table1 (и они делают это, потому что table1 эффективно объединен с каждой строкой в ​​table1), тогда удалите строку (т. Е. Каждую отдельную из них) из table1.

Вам необходимо удалить с join.

Delete from table1
Where table1.col1a = table2.col1a AND
   Table1.col2a= table2.col2b AND
   -- so on for each and every column required to match the target rows in table1. Or if you are unsure, all of them

К сожалению, SqlLite, похоже, не нравится эта (более старая) форма соединения в инструкции DELETE. Поэтому в SQLLite вам нужно будет использовать один из других методов, опубликованных здесь.

Согласно приведенному ниже примеру, он действительно работает в SELECT. Следующее было проверено на https://sqliteonline.com/

create table if not exists tbl1 (
  colA integer
);

create table if not exists tbl2 (
  colA integer
);

delete from tbl1
where tbl1.colA = tbl2.colA
;
-- Results in the error "no such column tbl2.colA" !?!?!?
-- Despite the fact that the syntax diagram appears to allow this https://www.sqlite.org/lang_delete.html

-- whereas the following runs just fine and performs an inner joins (you can insert your own data to verify)

select *
from tbl1, tbl2
where tbl1.colA = tbl2.colA
;

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...