2016-08-02 85 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