2016-08-02 57 views
1

首先,我有几个嵌套结构的表,我需要通过父表ID删除所有这些表的信息。一次删除相关信息并避免嵌套查询(PostgreSql)

例如,四个表:

Country 
country_id | country_name 

City 
city_id | country_id | city_name 

House 
house_id | city_id | house_name 

Room 
room_id | house_id | room_name 

我需要删除基于COUNTRY_ID的所有信息(国家本身要么)。

现在我使用嵌套查询,恐怕会超载系统。我现在使用的

例子:

DELETE FROM Room WHERE house_id IN (SELECT house_id FROM House WHERE city_id IN (SELECT city_id FROM City WHERE country_id = :country_id)) 
DELETE FROM House WHERE city_id IN (SELECT city_id FROM City ... 

有什么更紧凑的方式做到这一点? (这里性能最重要..)

+0

您可以用声明的外键'上删除cascade',然后直接删除该国(或城市) –

+0

谢谢!我认为这是我正在寻找的 –

回答

1

如果Room.house_id是一个外键引用House.house_id等等,那么你可以使用级联删除。也就是说,如果你有

foreign key (house_id) references House(house_id) 

然后使它

foreign key (house_id) references House(house_id) 
    on delete cascade 

指示数据库,只要通过一个给定的房间中引用的房子被删除,房间必须被删除了。如果您在层次结构中一直进行设置,那么在较高级别上删除将会“级联”到所有较低级别。 (在列定义中声明约束时,可以使用类似的语法。)

请注意,这是一个全数据库特征,但不是特定于查询的行为。启用级联删除很危险,因为它可能会无意中删除大量数据。另外,它的主要优点是简单。它可能会比你提出的查询序列好一点,因为只需要一个查询,并且因为你不需要在较低级别的子查询,但是这种差异可能不足以让你注意到。

+0

谢谢你提供这样一个翔实的答案! –

0

该查询更简单,如果你使用delete cascade通过@John Bollinger的建议则是你需要的只有一个:

delete from room 
using 
    house 
    inner join 
    city using (city_id) 
where 
    city.country_id = :country_id and 
    room.house_id = house.house_id