如何获得一个连续的,增加的数字,没有任何数字缺失的列?
可能重复:
如何在PostgreSQL查询中显示行号?
使用Postgresql中的标识重新sorting列
使用子select更新的PostgreSQLlogging重新sorting
我只是问在PostgreSQL是否存在这样的可能性,如果我有5行,并在一列中有数字1, 2, 3, 4, 5
并在这些列是不是主键,如果我删除说trird行,postgreSQL重新枚举这个专栏所以我可以有1, 2, 3, 4
而不是1, 2, 4, 5
?
从以前的答案改编。 当应用程序想要一个variables的tab-order (读取:在EAV模型中的logging)时,这种东西经常发生,这也可能是(备用)键的一部分。
-
priority
字段需要保持连续。 [这是tab-order ] - 在INSERT上:所有优先级> =新logging的logging都应该增加其优先级
- 同样的:在DELETE – >递减
- 如果一个logging的优先级被UPDATE改变,那么旧的和新的优先级值之间的logging应该使它们的优先级向上或向下移动。
- 避免recursion触发器调用:
- 基于触发器的更新将触发任何logging的
flipflag
。 - 然后他们testing
old.flipflag=new.flipflag
来检测真正的更新。 (那些不是由触发器造成的)
- 基于触发器的更新将触发任何logging的
-- Make some data DROP SCHEMA tmp CASCADE; CREATE SCHEMA tmp ; SET search_path=tmp; CREATE TABLE fruits ( id INTEGER NOT NULL PRIMARY KEY , priority INTEGER NOT NULL , flipflag boolean NOT NULL default false , zname varchar NOT NULL , CONSTRAINT unique_priority UNIQUE (priority) DEFERRABLE INITIALLY DEFERRED ); INSERT INTO fruits(id,zname,priority) VALUES (1 , 'Pear' ,4) ,(2 , 'Apple' ,2) ,(3 , 'Orange' ,1) ,(4 , 'Banana' ,3) ,(5 , 'Peach' ,5) ; -- Trigger functions for Insert/update/delete CREATE function shift_priority() RETURNS TRIGGER AS $body$ BEGIN UPDATE fruits fr SET priority = priority +1 , flipflag = NOT flipflag -- alternating bit protocol ;-) WHERE NEW.priority < OLD.priority AND OLD.flipflag = NEW.flipflag -- redundant condition AND fr.priority >= NEW.priority AND fr.priority < OLD.priority AND fr.id <> NEW.id -- exlude the initiating row ; UPDATE fruits fr SET priority = priority -1 , flipflag = NOT flipflag WHERE NEW.priority > OLD.priority AND OLD.flipflag = NEW.flipflag AND fr.priority <= NEW.priority AND fr.priority > OLD.priority AND fr.id <> NEW.id ; RETURN NEW; END; $body$ language plpgsql; CREATE function shift_down_priority() RETURNS TRIGGER AS $body$ BEGIN UPDATE fruits fr SET priority = priority -1 , flipflag = NOT flipflag -- alternating bit protocol ;-) WHERE fr.priority > OLD.priority ; RETURN NEW; END; $body$ language plpgsql; CREATE function shift_up_priority() RETURNS TRIGGER AS $body$ BEGIN UPDATE fruits fr SET priority = priority +1 , flipflag = NOT flipflag -- alternating bit protocol ;-) WHERE fr.priority >= NEW.priority ; RETURN NEW; END; $body$ language plpgsql; -- Triggers for Insert/Update/Delete CREATE TRIGGER shift_priority_u AFTER UPDATE OF priority ON fruits FOR EACH ROW WHEN (OLD.flipflag = NEW.flipflag AND OLD.priority <> NEW.priority) EXECUTE PROCEDURE shift_priority() ; CREATE TRIGGER shift_priority_d AFTER DELETE ON fruits FOR EACH ROW EXECUTE PROCEDURE shift_down_priority() ; CREATE TRIGGER shift_priority_i BEFORE INSERT ON fruits FOR EACH ROW EXECUTE PROCEDURE shift_up_priority() ; -- Do some I/U/D operations \echo Pears are Okay UPDATE fruits SET priority = 1 WHERE id=1; -- 1,4 SELECT * FROM fruits ORDER BY priority; \echo dont want bananas DELETE FROM fruits WHERE id = 4; SELECT * FROM fruits ORDER BY priority; \echo We want Kiwis INSERT INTO fruits(id,zname,priority) VALUES (4 , 'Kiwi' ,3) ; SELECT * FROM fruits ORDER BY priority;
结果:
Pears are Okay UPDATE 1 id | priority | flipflag | zname ----+----------+----------+-------- 1 | 1 | f | Pear 3 | 2 | t | Orange 2 | 3 | t | Apple 4 | 4 | t | Banana 5 | 5 | f | Peach (5 rows) dont want bananas DELETE 1 id | priority | flipflag | zname ----+----------+----------+-------- 1 | 1 | f | Pear 3 | 2 | t | Orange 2 | 3 | t | Apple 5 | 4 | t | Peach (4 rows) We want Kiwis INSERT 0 1 id | priority | flipflag | zname ----+----------+----------+-------- 1 | 1 | f | Pear 3 | 2 | t | Orange 4 | 3 | f | Kiwi 2 | 4 | f | Apple 5 | 5 | f | Peach (5 rows)