faw*_*zib 5 sql database postgresql relational-database sql-delete
考虑2个或更多表:
users (id, firstname, lastname)
orders (orderid, userid, orderdate, total)
Run Code Online (Sandbox Code Playgroud)
我希望删除与名字" 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';
Run Code Online (Sandbox Code Playgroud)
您也可以使用创建表 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)
);
Run Code Online (Sandbox Code Playgroud)
安排适当的级联删除是明智的,并且通常是对此的正确解决方案。对于某些特殊情况,还有另一种可能与此相关的解决方案。
如果您需要基于一组通用数据执行多次删除,则可以使用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)
Run Code Online (Sandbox Code Playgroud)
此示例刻意简单,因为我的目的不是争辩键映射等问题,而是说明如何对共享数据集执行两个或多个删除操作。这也可能更加复杂,包括更新命令等。
这是一个更复杂的示例(来自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)
Run Code Online (Sandbox Code Playgroud)
现在他的数据库是最新的。没有由于地址删除导致的完整性故障。请注意,虽然我们从更新和第一个删除中返回数据,但这并不意味着我们必须使用它。我不确定是否可以在没有返回数据的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';
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
15912 次 |
最近记录: |