PostgreSQL9.1 新特性之二: Writeable Common Table Expressions

PostgreSQL9.1 的这个特性可以重新利用数据更新(/Delete/Insert/Update)的结果集,并做进一步的处理,解释起来比较困难,先看看下面的例子。

备份数据

创建测试表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
mydb=> create table test_1 (id integer, name varchar(32));  
CREATE TABLE
mydb=> insert into test_1 values (1,'a'),(2,'b'),(3,'c');
INSERT 0 3
mydb=> create table test_1_bak as select * from test_1 where 1=2;
SELECT 0
mydb=> select * From test_1;
id | name
----+------
1 | a
2 | b
3 | c
(3 rows)
mydb=> select * from test_1_bak;
id | name
----+------
(0 rows)

场景一:CTE 基本用法

删除表 test_1 数据,并将删除的数据备份在表 test_1_bak

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
mydb=> WITH deleted as (delete from test_1 where id=1 returning id,name)  
mydb-> insert into test_1_bak select * From deleted;
INSERT 0 1

mydb=> select * from test_1;
id | name
----+------
2 | b
3 | c
(2 rows)

mydb=> select * from test_1_bak;
id | name
----+------
1 | a
(1 row)

备注:这个功能可以使用的历史数据归档上,比如删除上月数据时,可以将删除的数据归档到历史表上,节省操作步骤,提升效率。

场景二:显示已删除的数据

删除数据后,显示删除的数据,如下:

1
2
3
4
5
6
7
8
9
10
11
mydb=> WITH test_1_deleted as (delete from test_1 where id=2 returning *)  
mydb-> select * from test_1_deleted;
id | name
----+------
2 | b
(1 row)
mydb=> select * from test_1;
id | name
----+------
3 | c
(1 row)

备注:这个功能可以应用在清理数据时,将日志打出,确保删除的数据无误。当然,如果删除的数据量比较大,这点就不提倡了。

场景三:CTE 处理复杂的SQL逻辑

可以将稍复杂的业务逻辑放在一个SQL里实现,简化步骤,提高效率,如下所示;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
mydb=> insert into test_1 select generate_series(4,10),'c';  
INSERT 0 7

mydb=> select * from test_1;
id | name
----+------
3 | c
4 | c
5 | c
6 | c
7 | c
8 | c
9 | c
10 | c
(8 rows)

mydb=> create table test_2 (id integer , name varchar(32));
CREATE TABLE

mydb=> insert into test_2 select generate_series(1,10000),'AAA';
INSERT 0 10000

mydb=> select * From test_2 limit 3;
id | name
----+------
1 | AAA
2 | AAA
3 | AAA

mydb=> WITH test_1_deleted as (delete from test_1 where id<7 returning *) ,
mydb-> delete_count as (select count(*) as total from test_1_deleted)
mydb-> update test_2
mydb-> set name='this is a test'
mydb-> from delete_count d
mydb-> where id=d.total;
UPDATE 1

mydb=> select * From test_2 where name='this is a test';
id | name
----+----------------
4 | this is a test

原创文章,作者:306829225,如若转载,请注明出处:https://blog.ytso.com/236428.html

(0)
上一篇 2022年1月24日
下一篇 2022年1月24日

相关推荐

发表回复

登录后才能评论