Common Table Expression 是 pg 里极为重要的特性。这个特性简单的说就是 INSERT/UPDATE/DELTE 三项操作可以返回结果集。如:

update item set state = ‘A’ where state = ‘W’ returning *

update 语句通常视为 execute,而在 CTE 技术中却可以当做 query。

那么 CTE 有什么用呢?

1. 可以用于解决 upsert 问题。

Upserting via Writeable CTE - zillablog
http://xzilla.net/blog/2011/Mar/Upserting-via-Writeable-CTE.html

2. 可以避免先查询后更新的并发问题。

刚才看到有代码这样先查询符合条件的记录,再更新符合条件的记录:

select * from xx where cond

update xx set state = b where cond

先后执行两次查询,两次查询虽然是同一个cond,但前后2个查询之间可能发生难以预料的变更,命中的行集可能不同。改用 CTE 后,update 直接返回命中的行集,可消除因为前后查询不一致导致的并发问题。

3. 解决自动生成ID的取值问题。

在 oracle 里,对于自动递增主键 id,通常要先对 sequence 取下一个 id,然后再 insert,这个做法需要两次查询,效率不高,且对有 default 值的,或者 value 为函数结果的(如 sysdate),仍然无法得到新的值,往往还要执行一次 select 获得新增行的完整数据。

也就是说对于自动生成ID数据表要获得新行ID需要如下3步:

new id = select seq.nextval
insert into t (id, ..) values (new id)
select * from t where id = new id

对于一次插入多行的场景, 如(insert t select),要想得到新插入的行在 oracle 等数据库里更难表达。

引入CTE后,只需要在 insert 后加上 returning *,insert 动作就能返回新插入行的完整数据。

上面3点都是技术性问题,CTE 的重要意义不仅于此,CTE 真正的意义在于它彻底打通了所有的关系运算,利用 cte + 临时表 + with,大部分存储过程都不再需要,一个查询分步演算,就能解决所有问题——是所有问题!不是大部分问题!如对关系运算有充分理解可知此说不虚!


如欲对关系运算做更多了解,强烈推荐阅读这本:

《深度探索关系数据库:实践者的关系理论》((美)戴特 著)【简介_书评_在线阅读】 - 当当图书
http://product.dangdang.com/9309739.html?_ddclickunion=P-295132-156777_64_0__1|ad_type=0|sys_id=1#dd_refer=http%3A%2F%2Fc.duomai.com%2Ftrack.php%3Fsite_id%3D156777%26aid%3D64%26euid%3D%26t%3Dhttp%253a%252f%252fproduct.dangdang.com%252f9309739.html

这书很早了,到处都卖光了,自己找个PDF吧

Postgres中的Common Table Expression的更多相关文章

  1. CTE(Common Table Expression) 公用表表达式

    在编写T-SQL代码时,往往需要临时存储某些结果集.前面我们已经广泛使用和介绍了两种临时存储结果集的方法:临时表和表变量.除此之外,还可以 使用公用表表达式的方法.公用表表达式(Common Tabl ...

  2. SQLServer中的CTE(Common Table Expression)通用表表达式使用详解

    概述 我们经常会编写由基本的 SELECT/FROM/WHERE 类型的语句派生而来的复杂 SQL 语句.其中一种方案是需要编写在 FROM 子句内使用派生表(也称为内联视图)的 Transact-S ...

  3. 通用表表达式(Common Table Expression)

    问题:编写由基本的 SELECT/FROM/WHERE 类型的语句派生而来的复杂 SQL 语句. 方案1:编写在From子句内使用派生表(内联视图)的T-SQL查询语句. 方案2:使用视图 方案3:使 ...

  4. with as (cte common table expression) 公共表表达式

    SQL中 with as 的用法——使用公用表表达式(CTE)  公用表表达式 (CTE) 可以认为是在单个 SELECT.INSERT.UPDATE.DELETE 或 CREATE VIEW 语句的 ...

  5. PostgreSQL: WITH Queries (Common Table Expressions)

    WITH 允许在 SELECT 语句中定义"表"的表达式,这个"表"的表达式称之为"公共表表达式(Common Table Expression)&q ...

  6. postgres中的视图和物化视图

    视图和物化视图区别 postgres中的视图和mysql中的视图是一样的,在查询的时候进行扫描子表的操作,而物化视图则是实实在在地将数据存成一张表.说说版本,物化视图是在9.3 之后才有的逻辑. 比较 ...

  7. Using Recursive Common table expressions to represent Tree structures

    http://www.postgresonline.com/journal/archives/131-Using-Recursive-Common-table-expressions-to-repre ...

  8. My Sql 中要Alter Table的同学请注意!!!

    首先我建议你在对MySQL表做DDL操作时: 1 执行 show processlist 查看,要操作的表(数据库对象)是否处于锁状态 if("未锁定") { 执行DDL语句 }e ...

  9. html中使用js+table 实现分页

    本文在html中利用js+table实现分页.主要思想是先对table中的所有数据隐藏,然后通过当前页面(currPageNum)来计算当前页要显示的行,并显示出来,首页.下一页.上一页.尾页都依此来 ...

  10. postgres中几个复杂的sql语句

    postgres中几个复杂的sql语句 需求一 需要获取一个问题列表,这个问题列表的排序方式是分为两个部分,第一部分是一个已有的数组[0,579489,579482,579453,561983,561 ...

随机推荐

  1. ZRAM的Swap功能和 SWAP分区有什么区别

    ZRAM(压缩内存块设备)和传统的SWAP分区都是Linux系统中用来增加可用内存的方法,但它们的工作原理和实现方式有很大的区别: ZRAM 压缩内存:ZRAM使用压缩算法将数据存储在内存中.这样,当 ...

  2. 关于自定义事件父子组件传值问题 $event

    1.$event 是 vue 提供的特殊变量,用来表示原生的事件参数对象 event 1.1在原生事件中,$event是事件对象 可以点出来属性 2.在原生事件中,$event是事件对象,在自定义事件 ...

  3. 创建一个简单的基于MyBatis的项目

  4. 如何解决token过期问题 ?

    首先 token 过期会导致请求不到数据 , 就不能准确渲染页面 ,此时的错误配置项的token是过期的,只要更新了token 拿着原先的配置项重新请求数据即可 :但是如果更新token的时候请求错误 ...

  5. DataDream:调一调更好,基于LoRA微调SD的训练集合成新方案 | ECCV'24

    尽管文本到图像的扩散模型已被证明在图像合成方面达到了最先进的结果,但它们尚未证明在下游应用中的有效性.先前的研究提出了在有限的真实数据访问下为图像分类器训练生成数据的方法.然而,这些方法在生成内部分布 ...

  6. centos 安装mbstring(mb_strlen )

    部署onethink框架的时候,检测到mb_strlen未支持, 在网上检索一大堆教程,最多的就是先检测一下需要安装的安装包 yum search php 楼主小白满心欢喜地输入,一对照返回的结果, ...

  7. 入门级别 Nginx 常用配置清单

    本文为转发文章,转发来自"https://mp.weixin.qq.com/s/ipUHaFPcDfIM9MsyqDGSEg",觉得不错分享给大家 Nginx 是一个高性能的 HT ...

  8. 鱼香ROS一键安装软件

    一行代码-解决人生烦恼 推荐语:一行代码搭建机器人开发环境(ROS/ROS2/ROSDEP) 开源地址:https://github.com/fishros/install 一键安装指令 wget h ...

  9. [rCore学习笔记 030] 虚拟地址与地址空间

    时隔很久,终于忙里偷闲可以搞一搞rCore,上帝啊,保佑我日更吧,我真的很想学会. 导读部分 首先还是要看官方文档. 我决定看一遍然后自己表述一遍(智将). 这里反复提到MMU,就是因为之前学MCU的 ...

  10. 噢!JavaScript (2):对数组要小心使用delete

    最近在重写我自己的静态博客生成器,虽然遇到的小问题挺多,但今早这个问题令我印象深刻. 发现问题 博客的文章基础数据储存在main.json中,其中专门有数组dateindex来储存经过排列后的文章顺序 ...