如果标题没有正确传达问题,我们深表歉意。
如果我有一个名为 Person 的 Postgres 表,其中包含以下列和数据:
name | age | order |
John | 42 | 1 |
Sam | 27 | 2 |
Phil | 19 | 3 |
顺序列是一个 float ,用于确定客户端显示人员列表的顺序。
是否有最佳的性能方法来插入具有现有订单的人员,但委托(delegate)数据库自动递增订单列中的值?如果是这样,怎么办?
例如,如果我插入一个新人(Emma, 56, 2)
,我希望结果为
name | age | order |
John | 42 | 1 |
Sam | 27 | 3 |
Phil | 19 | 4 |
Emma | 56 | 2 |
请注意,Sam 和 Phil 现在的订单已增加。
可能的解决方案: 我可以利用 float 并获得先前订单值和当前订单值的平均值。因此,在上面的示例中,它将是 1(对于 John)+ 2(对于插入中的 Emma)/2。Emma 的新顺序将为 1.5,如下所示,非常适合:
name | age | order |
John | 42 | 1 |
Sam | 27 | 2 |
Phil | 19 | 3 |
Emma | 56 | 1.5 |
但这需要多个数据库调用,因此出现了问题。
编辑:虽然我在最终实现中采用了乔治·约瑟夫的答案,但实际回答问题的正确答案是clamp的。因此我将他的回答标记为已接受。
最佳答案
如果您想更新现有条目,请按以下步骤操作:
首先检查新值是否与现有值冲突。如果是这样,请将现有值增加 1(这仍然与整数有关)。
我使用 sort_order
而不是 order
,因为后者在 SQL 中是保留的。
CREATE FUNCTION person_check_sort_order() RETURNS TRIGGER AS
$def$
BEGIN
PERFORM * FROM person WHERE sort_order = new.sort_order;
IF FOUND THEN
UPDATE person SET sort_order = sort_order + 1 WHERE sort_order >= new.sort_order;
END IF;
RETURN new;
END;
$def$
LANGUAGE plpgsql;
CREATE TRIGGER person_insert_trg BEFORE INSERT ON person
FOR EACH ROW EXECUTE PROCEDURE person_check_sort_order();
或者你可以递归地进行。这也适用于更新,并在达到订单号间隙时停止(假设整数值):
CREATE OR REPLACE FUNCTION person_check_sort_order() RETURNS TRIGGER AS
$def$
BEGIN
PERFORM * FROM person WHERE sort_order = new.sort_order;
IF FOUND THEN
UPDATE person SET sort_order = sort_order + 1 WHERE sort_order = new.sort_order;
END IF;
RETURN new;
END;
$def$
LANGUAGE plpgsql;
--DROP TRIGGER person_insert_trg ON person;
CREATE TRIGGER person_insert_trg BEFORE INSERT OR UPDATE OF sort_order ON person
FOR EACH ROW EXECUTE PROCEDURE person_check_sort_order();
关于sql - 有没有办法在添加新值时动态更新/增加列值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63217970/