2012-04-13 71 views
16

我有這些表:如何從多個表中刪除數據?

 
event  (evt_id, evt_code, reg_id) 

magnitude (mag_id, evt_id, value) 

trace  (trace_id, pt_id) 

point  (pt_id, evt_id) 

我想刪除有關evt_id=1139所有表中的所有行。
我該怎麼做?

回答

17

如果你能控制你的模式,我會使模式使用cascading deletes

從文章(翻譯成您的例子更貼切的部分)

CREATE TABLE point 
(
    pt_id integer PRIMARY KEY, 
    evt_id integer REFERENCES event ON DELETE CASCADE 
) 

如果你設置了級聯,那麼你可以從主事件表中刪除和所有其他的表將被清理自動

否則,您需要先刪除所有引用,然後刪除主表。你應該這樣做在一個事務中保持數據一致

BEGIN; 
DELETE FROM trace WHERE EXISTS 
    (SELECT 1 FROM point WHERE evt_id = 1139 AND trace.pt_id = point.pt_id); 
DELETE FROM point where evt_id = 1139; 
DELETE FROM magnitude where evt_id = 1139; 
DELETE FROM event where evt_id = 1139; 
COMMIT; 
-3
$delete = 1139; 
$query = "DELETE FROM event, magnitude, point WHERE evt_id = '$delete'"; 
mysql_query($query, $con); 
$query = "DELETE FROM trace WHERE pt_id = '$delete'"; 

或者只是粘貼聲明成.sql文件並運行它,或者到SQL軟件查詢窗口,或將其放置在以.php文件並在服務器上運行。

+1

據我所知,你不能從這樣的多個表中刪除(但我可能是錯的)。但是,至少'trace'沒有evt_id列 – 2012-04-13 17:18:13

+0

數據庫位於服務器上。我如何運行這個查詢文件? – user1202766 2012-04-13 17:18:43

+0

是的,這是真正的痕跡沒有一個evt_id列,但有pt_id這是從evt_id列的點表...這是令人困惑! – user1202766 2012-04-13 17:20:34

-1

我假設不同表中的id對應並用於鏈接。 我還以爲你要刪除所有的跟蹤點allthough他們只是間接與evt_id

您可以從所有的表刪除記錄如下:

DELETE event , magnitude, trace, point 
FROM event left join magnitude on event.evt_id = magnitude.evt_id 
    left join point on event.evt_id = point.evt_id 
     left join trace on point.pt_id = trace.trace_id 
where event_id=1139 
+5

這隻會在MySQL中工作,並且OP已將此問題從mysql和postgresql重新標記爲僅postgresql – 2012-04-13 18:00:59

7

在你的問題中唯一的非平凡元素從表中刪除trace。我想這是可以安全地假設trace.pt_id是參考point.pt_id

要麼你定義一個foreign key with ON DELETE CASCADE,只是忘記表trace(作爲已經pointed out by @kevin),或者你必須照顧手動依賴行。

因爲PostgreSQL 9.1您可以使用data-modifying CTEs

BEGIN; 

WITH x AS (
    DELETE FROM point WHERE evt_id = 1139 
    RETURNING pt_id 
    ) 
DELETE FROM trace 
USING x 
WHERE trace.pt_id = x.pt_id; 

DELETE FROM magnitude WHERE evt_id = 1139; 

DELETE FROM event WHERE evt_id = 1139; 

COMMIT; 

DELETE FROM point回報的RETURNING clause所有受影響的pt_id - 這些都是反過來用於從trace刪除所有相應的行。

您沒有提到併發性是否是您的情況中的問題。如果是,並且您希望避免在刪除之間的短時間窗口中出現可能的結果,其中evt_id = 1139的行在一個表格中存在但已經從另一個表格中刪除,則將其全部包裝到交易中。
如果這不關心你,請忽略BEGINCOMMIT