当在做测试或者需求就是需要更新10条数据中的第二行到第八行的数据,那应该这么办?开始的时候我也是百思不得其解,也就是知道了ctid用法才解决了类似的问题。
下面就直接说一下例子,
一个简单的表mytest7,
"ctid"
"id"
"name_1"
"name_2"
"name_3"
"(0,1)"
"1"
"name_11"
"name_21"
"name_31"
"(0,2)"
"2"
"name_12"
"name_22"
"name_32"
"(0,3)"
"3"
"name_13"
"name_23"
"name_33"
"(0,4)"
"4"
"name_14"
"name_24"
"name_34"
"(0,5)"
"5"
"name_15"
"name_25"
"name_35"
"(0,6)"
"6"
"name_16"
"name_26"
"name_36"
"(0,7)"
"7"
"name_17"
"name_27"
"name_37"
"(0,8)"
"8"
"name_18"
"name_28"
"name_38"
"(0,9)"
"9"
"name_19"
"name_29"
"name_39"
"(0,10)"
"10"
"name_110"
"name_210"
"name_310"
如果选择需要将第2行到第4行数据的name_3字段的值全部更新为‘name333’
update mytest7 set name_3 = 'name333' where ctid>='(0,2)'::tid and ctid <= '(0,4)'::tid;
当然,在这份表数据中并不一定要使用ctid,而使用ctid的情况下是当一个表中的数据没有能力区分与其他行的字段或者组合字段时而使用的,例如表mytest8的数据情况,
"id"
"name_1"
"name_2"
"name_3"
"1"
"name_11"
"name_22"
"name_33"
"1"
"name_11"
"name_22"
"name_33"
"1"
"name_11"
"name_22"
"name_33"
"1"
"name_11"
"name_22"
"name_33"
"1"
"name_11"
"name_22"
"name_33"
"2"
"name_11"
"name_22"
"name_33"
"2"
"name_11"
"name_22"
"name_33"
"2"
"name_11"
"name_22"
"name_33"
"2"
"name_11"
"name_22"
"name_33"
"2"
"name_11"
"name_22"
"name_33"
update mytest8 t1 set name_3 = 'name333'
from (select ctid,* from mytest8 where ctid >='(0,2)'::tid and ctid<='(0,4)')t2
where t1.ctid = t2.ctid;
这里还需要注意的是,ctid会随着字段值的变化而变化,即当你update过后原来的ctid=(0,2)就不存在了,那么第二次时你就不能按照上面的语句来做了,而是需要:
update mytest8 t1 set name_3 = 'name333'
from (select * from (select ctid,row_number()over() as rown,* from mytest8)tt where rown>=2 and rown<=4)t2
where t1.ctid = t2.ctid;
在实际的情况下可能会有不同的解决方式,但是关键点就是在ctid的唯一性这一点的使用,当delete的时候也是一样的操作。
原文链接:https://www.f2er.com/postgresql/195191.html