Postgresql

Postgresql觸發器在刪除後更新整個表

  • November 10, 2016

我有一個看起來像這樣的表格“測量”(最後一列有空單元格)

ser_nr | meas_ser | meas_value | last_meas
-------+----------+------------+-----------
 A1   |    1     |    12      |  (False)
 A1   |    2     |    5.5     |  (False)
 A1   |    3     |    5.12    |  (False)
 A1   |    4     |    5.01    |  (True)
 B1   |    1     |    2       |  (False)
 B1   |    2     |    2.03    |  (True)

http://sqlfiddle.com/#!15/bcd6b(創建表等連結)

我需要這個來查詢“select … where last_meas=True”

我為“插入後”編寫了一個觸發器,這適用於新插入的行。但是我能做些什麼來更新整個表呢?

例如:我想刪除 meas_value “5.01” 的 A1 行。必須有一個對整個剩餘表執行並更新 last_meas 列的函式(在此範例中,第三行現在應該為 True)。我可以使用“每行刪除後”觸發一個函式,但使用這種方法我只能訪問所有已刪除的行。

我通過使用生成視圖找到了解決方法

SELECT * FROM measurements AS m LEFT OUTER JOIN (SELECT m.ser_nr, 
   max(m.meas_ser) AS meas_ser, TRUE AS last_meas FROM measurements AS 
   m GROUP BY m.ser_nr ) AS last_ms USING (ser_nr, meas_ser);

但這只會產生“真”而不是“假”。

有沒有更簡單的方法來做到這一點?

您可以將這個更簡單/更便宜的查詢用於您的視圖或 CTE,或者只是一個子查詢:

SELECT ser_nr, meas_ser, meas_value
    , row_number() OVER (PARTITION BY ser_nr ORDER BY meas_ser DESC) = 1 AS last_meas
FROM   measurements;

SQL小提琴。

當您在小提琴中添加了 PK 約束時,這裡沒有重複或 NULL 值的極端情況問題:

ALTER TABLE measurements ADD CONSTRAINT measurements_pk PRIMARY KEY (ser_nr,meas_ser);

如果您只需ser_no要從大表中選擇一小部分,關聯的索引也將有助於加快速度。

是的,與嘗試使基表中的行保持最新相比,這種動態方法帶來的麻煩(面對並發寫訪問時的一致性!)的可能性要小得多。

引用自:https://dba.stackexchange.com/questions/154717