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)