簡體   English   中英

Postgresql從多個表中刪除多行

[英]Postgresql delete multiple rows from multiple tables

考慮2個或更多表:

users (id, firstname, lastname)
orders (orderid, userid, orderdate, total)

我希望刪除與名字“ Sam ”匹配的所有用戶及其訂單 在mysql中,我通常會離開加入。 在此示例中,userid對我們來說是未知的。

查詢的正確格式是什么?

http://www.postgresql.org/docs/current/static/sql-delete.html

DELETE 
FROM orders o
USING users u
WHERE o.userid = u.id
  and u.firstname = 'Sam';

DELETE 
FROM users u
WHERE u.firstname = 'Sam';

您還可以使用ON delete cascade創建表

http://www.postgresql.org/docs/current/static/ddl-constraints.html

CREATE TABLE order_items (
    product_no integer REFERENCES products ON DELETE RESTRICT,
    order_id integer REFERENCES orders ON DELETE CASCADE,
    quantity integer,
    PRIMARY KEY (product_no, order_id)
);

安排適當的級聯刪除是明智的,通常是正確的解決方案。 對於某些特殊情況,還有另一種可能相關的解決方案。

如果需要根據一組通用數據執行多次刪除,則可以使用CTE

很難想出一個簡單的例子,因為這個主要用例可以通過級聯刪除來解決。

對於該示例,我們將刪除表A中的所有項,其值在我們從表B中刪除的值集中。通常這些是鍵,但在不是,但是不能使用級聯刪除。

要解決此問題,請使用CTE

WITH Bdeletes AS (
    DELETE from B where IsSomethingToDelete = true returning ValueThatRelatesToA
)
delete from A where RelatedValue in (select ValueThatRelatesToA from Bdeletes)

這個例子是故意簡單的,因為我的觀點不是爭論密鑰映射等,而是說明如何從共享數據集中執行兩個或多個刪除。 這也可能更復雜,包括更新命令等。

這是一個更復雜的例子(來自Darth Vader的個人數據庫)。 在這種情況下,我們有一個引用地址表的表。 我們需要刪除地址表中的地址,如果它們在他被摧毀的行星列表中。 我們希望使用此信息從人員表中刪除,但僅限於他們在地球上(或在他的獎杯 - 殺戮名單上)

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)

現在他的數據庫是最新的。 沒有因地址刪除導致的完整性故障。 請注意,雖然我們從更新和第一次刪除返回數據,但這並不意味着我們必須使用它。 我不確定你是否可以在沒有返回數據的CTE中刪除(我的SQL在使用從更新返回時可能也是錯誤的 - 我無法測試運行這個因為Darth V.是在胡思亂想的心情。

使用級聯刪除將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';

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM