我有一个PostgreSQL数据库版本9.5.0。
表格UserComments
的创建方式如下:
create table UserComments (
userId integer,
commentNr integer,
comment text,
UNIQUE (userId, commentNr)
);
无法更改表格,也无法添加额外的表格。
我想在commentNr
上创建一个序列(换句话说:自动递增值),具体取决于userId
条目的数量。
对于具有相同userId
的每个新条目,其值应递增
示例:
userId | commentNr | comment -------|-----------|--------- 1 | 1 | blabla 1 | 2 | more bla 2 | 1 | myownbla 1 | 3 | evenmorebla
我已经找到了“触发器”和“窗口函数”的一些答案,但由于我不允许更改表,因此没有一个对我有用。
最佳解决方案是每个INSERT
自动counts
/计算commentNr
的触发器,以便我可以使用
insert into user(userId, comment) values ('1', 'bla');
任何帮助将不胜感激。
答案 0 :(得分:0)
对于这样的简单情况,没有必要创建触发器。可以在CTE或子查询中计算正确的序列并插入。
注意:如果使用下面的sql,则必须指定插入的userId
两次
INSERT INTO "user" ("userId", "commentNr", "comment") (
WITH
nextval AS (
SELECT COALESCE(MAX("commentNr"),0)+1 commentNr
FROM "user"
WHERE "userId" = '1'
)
SELECT '1', nextval.commentNr, 'bla'
FROM nextval
);
答案 1 :(得分:0)
要自动计算commentNr字段,您可以使用TRIGGER:
CREATE INDEX i1 ON UserComments (userId, commentNr DESC);
CREATE OR REPLACE FUNCTION set_commentNr() RETURNS TRIGGER AS $sql$
BEGIN
NEW.commentNr = coalesce(max(commentNr) + 1, 1) FROM UserComments WHERE UserId = NEW.userID;
RETURN NEW;
END;
$sql$ LANGUAGE plpgsql STABLE;
CREATE TRIGGER ins_comment BEFORE INSERT ON UserComments FOR EACH ROW EXECUTE PROCEDURE set_commentNr();
小测试:
insert into userComments (userId, comment) values ('1', 'bla');
insert into userComments (userId, comment) values ('1', 'bla');
insert into userComments (userId, comment) values ('2', 'bla');
insert into userComments (userId, comment) values ('1', 'bla');
insert into userComments (userId, comment) values ('2', 'bla');
SELECT * FROM userComments;
userid | commentnr | comment
--------+-----------+---------
1 | 1 | bla
1 | 2 | bla
2 | 1 | bla
1 | 3 | bla
2 | 2 | bla
(5 rows)
创建索引i1以提高计算下一个值的性能:
QUERY PLAN
-------------------------------------------------------------------------------------------------------------------------------------
Result (cost=4.17..4.18 rows=1 width=4) (actual time=0.032..0.032 rows=1 loops=1)
InitPlan 1 (returns $0)
-> Limit (cost=0.15..4.17 rows=1 width=4) (actual time=0.026..0.026 rows=1 loops=1)
-> Index Only Scan using i1 on usercomments (cost=0.15..24.27 rows=6 width=4) (actual time=0.021..0.021 rows=1 loops=1)
Index Cond: ((userid = 1) AND (commentnr IS NOT NULL))
Heap Fetches: 1
Planning time: 0.238 ms
Execution time: 0.095 ms