WITH
允許您定義用於SELECT
查詢的「臨時表」。比如,我最近寫了這樣的查詢,兩組之間計算的變化:
-- Let o be the set of old things, and n be the set of new things.
WITH o AS (SELECT * FROM things(OLD)),
n AS (SELECT * FROM things(NEW))
-- Select both the set of things whose value changed,
-- and the set of things in the old set but not in the new set.
SELECT o.key, n.value
FROM o
LEFT JOIN n ON o.key = n.key
WHERE o.value IS DISTINCT FROM n.value
UNION ALL
-- Select the set of things in the new set but not in the old set.
SELECT n.key, n.value
FROM o
RIGHT JOIN n ON o.key = n.key
WHERE o.key IS NULL;
通過定義「表」 o
和n
在上面,我是能夠避免重複表達things(OLD)
和things(NEW)
。
當然,我們可以使用FULL JOIN
來消除UNION ALL
,但在我的特殊情況下我無法做到這一點。
如果我正確理解您的查詢,它這樣做:
我不認爲WITH
會簡化你的情況。它可能會稍微更優雅的使用FROM
條款,但:
update global.prospect psp
set status = status || '*'
from (select psp_id
from global.prospect
where status = 'new' or status = 'reset'
order by request_ts
limit 1
) p2
where psp.psp_id = p2.psp_id
returning psp.*;
未經檢驗。讓我知道它是否有效。
這幾乎是你有什麼已經,除了:
這可以很容易地擴展到更新多行。在使用子查詢表達式的版本中,如果子查詢更改爲產生多行,則查詢將失敗。
我沒有在子查詢中別名global.prospect
,所以它更容易閱讀。由於這使用了FROM
子句,因此如果意外引用正在更新的表,則會出現錯誤。
在您的版本中,每個單項都會遇到子查詢表達式。雖然PostgreSQL應該對此進行優化並且只對表達式進行一次評估,但如果您不小心引用psp
中的列或添加易失性表達式,則此優化將消失。
根據文檔,在PostgreSQL 9.1中添加了在INSERT和UPDATE語句之上使用WITH [RECURSIVE]。 – 2012-01-04 04:08:20
@JoeyAdams - 使用dml - 理解另一層洋蔥 – 2012-01-04 04:16:34