Выбор строк для удаления с неявным соединением - PullRequest
0 голосов
/ 05 февраля 2020

У меня есть две таблицы с отношением многие-к-одному. Я могу выбрать элементы в «дочерней» таблице с критериями в родительской таблице, используя неявное соединение:

select * from child,parent where child.parentid=parent.id and parent.name like 'foobar%'

Существует ли лучший (более эффективный, более элегантный) способ удаления дочерних элементов, чем простой:

delete from child where child.parentid in (select id from parent where parent.name like 'foobar%')

Этот ответ подсказывает, что я мог бы сделать:

delete child from child,parent where child.parentid=parent.id and parent.name like 'foobar%'

Но на PostgreSql (через Белку SQL) я получаю синтаксическую ошибку. .. конечно, у меня длинные имена таблиц, поэтому фактический запрос больше похож на:

delete c from child c, parent p where c.parentid=p.id and p.name like 'foobar%'

Так это поддерживается PG, или есть другой способ?

Бонусные баллы: могу ли я удалить элементы из двух таблиц, используя:

delete from child,parent where child.parentid in (select id from parent where parent.name like 'foobar%')

Ответы [ 3 ]

1 голос
/ 05 февраля 2020

Вы можете удалить из обеих таблиц в одном операторе, используя данные, модифицирующие CTE :

with deleted_parent as (
  delete from parent
  where name like 'foobar%'
  returning id
)
delete from child
where id in (select id from deleted_parent)
0 голосов
/ 05 февраля 2020

В postgres синтаксис того, что вы пытаетесь сделать, это использовать «USING»

delete from child C USING parent P where C.parentid=P.id 
and P.name like 'foobar%'
0 голосов
/ 05 февраля 2020

Я бы предложил использовать возможности вашей базы данных, создав внешний ключ с опцией on delete cascade:

alter table child
    add constraint child_parent_fk 
    foreign key (parentid) references parent(id)
    on delete cascade;

Помимо обеспечения целостности данных во всех таблицах, это будет управлять удалением в дочерняя таблица при удалении родителя, так что вы можете просто ...

delete from parent where name like 'foobar%'

... и быть уверенным, что дочерние элементы будут соответственно удалены.

...