在 SQL 中使用 WITH 子句的指南 [英] Guidance on using the WITH clause in SQL
问题描述
我了解如何将 WITH
子句用于递归查询 (!!),但我无法理解其一般用途/功能.
I understand how to use the WITH
clause for recursive queries (!!), but I'm having problems understanding its general use / power.
例如,以下查询更新一条记录,其 id 是通过使用通过时间戳返回第一条记录的 id 的子查询来确定的:
For example the following query updates one record whose id is determined by using a subquery returning the id of the first record by timestamp:
update global.prospect psp
set status=status||'*'
where psp.psp_id=(
select p2.psp_id
from global.prospect p2
where p2.status='new' or p2.status='reset'
order by p2.request_ts
limit 1 )
returning psp.*;
这会是使用 WITH
包装器而不是相对难看的子查询的好选择吗?如果有,为什么?
Would this be a good candidate for using a WITH
wrapper instead of the relatively ugly sub-query? If so, why?
推荐答案
如果可以并发写入访问涉及的表,则在以下查询中存在竞争条件.考虑:
If there can be concurrent write access to involved tables, there are race conditions in the following queries. Consider:
您的示例可以使用 CTE(公用表表达式),但它不会为您提供子查询无法做到的任何事情:
Your example can use a CTE (common table expression), but it will give you nothing a subquery couldn't do:
WITH x AS (
SELECT psp_id
FROM global.prospect
WHERE status IN ('new', 'reset')
ORDER BY request_ts
LIMIT 1
)
UPDATE global.prospect psp
SET status = status || '*'
FROM x
WHERE psp.psp_id = x.psp_id
RETURNING psp.*;
返回的行将是更新的版本.
如果您想将返回的行插入到另一个表中,这就是 WITH
子句变得必不可少的地方:
If you want to insert the returned row into another table, that's where a WITH
clause becomes essential:
WITH x AS (
SELECT psp_id
FROM global.prospect
WHERE status IN ('new', 'reset')
ORDER BY request_ts
LIMIT 1
)
, y AS (
UPDATE global.prospect psp
SET status = status || '*'
FROM x
WHERE psp.psp_id = x.psp_id
RETURNING psp.*
)
INSERT INTO z
SELECT *
FROM y;
PostgreSQL 9.1 添加了使用 CTE 的数据修改查询.WITH
查询 (CTE) 手册.一个>
Data-modifying queries using CTEs were added with PostgreSQL 9.1.
The manual about WITH
queries (CTEs).
这篇关于在 SQL 中使用 WITH 子句的指南的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!