Postgresql从多个表中删除多行
考虑两个或多个表:Postgresql从多个表中删除多行,sql,database,postgresql,relational-database,sql-delete,Sql,Database,Postgresql,Relational Database,Sql Delete,考虑两个或多个表: users (id, firstname, lastname) orders (orderid, userid, orderdate, total) 我希望删除所有与名字“Sam”匹配的用户及其订单。在mysql中,我通常使用左连接。在本例中,用户ID对我们来说是未知的 查询的正确格式是什么? 您还可以在删除级联时使用创建表 使用级联删除将userid定义为users(id)的外键,例如: create table users ( id int primary k
users (id, firstname, lastname)
orders (orderid, userid, orderdate, total)
我希望删除所有与名字“Sam”匹配的用户及其订单。在mysql中,我通常使用左连接。在本例中,用户ID对我们来说是未知的
查询的正确格式是什么?
您还可以在删除级联时使用创建表
使用级联删除将userid
定义为users(id)
的外键,例如:
create table users (
id int primary key,
firstname text,
lastname text);
create table orders (
orderid int primary key,
userid int references users (id) on delete cascade,
orderdate date,
total numeric);
delete from users
where firstname = 'Sam';
安排适当的级联删除是明智的,通常是正确的解决方案。
对于某些特殊情况,有另一种解决方案是相关的
如果需要基于一组公共数据执行多次删除,可以使用CTE
很难想出一个简单的例子,因为级联删除可以涵盖这方面的主要用例
例如,我们将删除表A中的所有项,这些项的值在我们要从表B中删除的值集中。通常这些项是键,但如果不是键,则不能使用级联删除
要解决这个问题,您需要使用CTEs
WITH Bdeletes AS (
DELETE from B where IsSomethingToDelete = true returning ValueThatRelatesToA
)
delete from A where RelatedValue in (select ValueThatRelatesToA from Bdeletes)
这个示例非常简单,因为我的目的不是讨论键映射等问题,而是展示如何对共享数据集执行两次或多次删除。
这也可能更加复杂,包括更新命令等
下面是一个更复杂的例子(来自达斯·维德的个人数据库)。在本例中,我们有一个引用地址表的表。我们需要从地址表中删除地址,如果它们在他被摧毁的行星列表中。我们想使用此信息从人员表中删除,但前提是他们在这个星球上(或在他的战利品杀死名单上)
现在他的数据库是最新的。没有因地址删除而导致的完整性故障。
注意,当我们从更新和第一次删除返回数据时,并不意味着我们必须使用它。我不确定是否可以在没有返回数据的情况下在CTE中进行删除(我的SQL在使用从更新返回时可能也有错误-由于达斯V.情绪暴躁,我无法测试运行此操作。非常感谢!这将对未来有所帮助。我发现您缺乏信心令人不安。如果您不需要返回子句,则返回NULL将是一个可接受的替代项…或者您可以完全忽略我。)t、 提示:应该可以写“从使用AddressesToDelete的人中删除,其中AddressId=AddressesToDelete.id和OffPlanet=false和Tropykill=false”。
create table users (
id int primary key,
firstname text,
lastname text);
create table orders (
orderid int primary key,
userid int references users (id) on delete cascade,
orderdate date,
total numeric);
delete from users
where firstname = 'Sam';
WITH Bdeletes AS (
DELETE from B where IsSomethingToDelete = true returning ValueThatRelatesToA
)
delete from A where RelatedValue in (select ValueThatRelatesToA from Bdeletes)
with AddressesToDelete as (
select AddressId from Addresses a
join PlanetsDestroyed pd on pd.PlanetName = a.PlanetName
),
PeopleDeleted as (
delete from People
where AddressId in (select * from AddressesToDelete)
and OffPlanet = false
and TrophyKill = false
returning Id
),
PeopleMissed as (
update People
set AddressId=null, dead=(OffPlanet=false)
where AddressId in (select * from AddressesToDelete)
returning id
)
Delete from Addresses where AddressId in (select * from AddressesToDelete)