WITH的PostgreSQL 文档显示了以下示例:
WITH regional_sales AS (
SELECT region, SUM(amount) AS total_sales
FROM orders
GROUP BY region
), top_regions AS (
SELECT region
FROM regional_sales
WHERE total_sales > (SELECT SUM(total_sales)/10 FROM regional_sales)
)
SELECT region,
product,
SUM(quantity) AS product_units,
SUM(amount) AS product_sales
FROM orders
WHERE region IN (SELECT region FROM top_regions)
GROUP BY region, product;
它还指出:
WITH 查询的一个有用属性是每次执行父查询时它们只被评估一次,即使它们被父查询或同级 WITH 查询多次引用。
我看到它WITH
可以用于其他事情,比如递归评估。但是在上面的例子中,使用和创建临时表有什么重要的区别吗?WITH
有一些细微的区别,但没有太大的区别:
ON COMMIT DROP
临时表在会话(或者,如果,事务)的生命周期中存在,而WITH
始终严格限制在查询范围内;WITH
表表达式;VACUUM
在系统目录上生成的工作WITH
不会,它需要额外的往返来创建/填充它,并且需要在服务器的缓存管理中进行额外的工作,因此它的效率略低。总的来说,您应该更喜欢
WITH
临时表,除非您知道您将从创建索引中受益。但是,另一个选项,即
FROM
子句中的子查询,具有非常不同的优势。特别是它可以内联,并且限定符可以上拉/下推。我在最近的一篇博客文章中谈到了这一点。