[英]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.