我有一个来自一个表(FileInstance)的多个SELECT的请求,这些SELECT使用MAX函数。
在此INSERT语句中SELECT MAX(Sequence) FROM FileInstance
会给出相同的结果吗?
是否有可能在这些SELECT之间添加记录,我将捕获不同的值?
INSERT INTO
FileInstance (Data, Size, FileID, ChangesetID)
VALUES
(
(SELECT Data FROM FileInstance WHERE FileID=%1 AND Sequence=(SELECT MAX(Sequence) FROM FileInstance WHERE FileID=%1)),
(SELECT Size FROM FileInstance WHERE FileID=%1 AND Sequence=(SELECT MAX(Sequence) FROM FileInstance WHERE FileID=%1)),
%1,
NULL
);
对于cource,我认为两个调用SELECT MAX(Sequence)FROM FileInstance WHERE FileID =%1将被转换为一个调用,但我只是想确定。
我使用postgresql 9.2。 谢谢!
答案 0 :(得分:2)
是的,该语句在数据库运行时会看到一致的数据库视图。因此,两个子选择将返回相同的值。
编辑:我认为也可能需要有关并发插入的说明。如果某些其他事务在语句运行时插入更高的序列号,则如果序列上有唯一索引,则可能导致错误。
如果序列列不需要无间隙,则使用真实序列可能是更好的解决方案。
如果您想避免并发事务的问题,您可能希望将隔离级别更改为" serializable"在运行插入之前。
但是你的陈述是非常低效的。这可以简化为:
INSERT INTO FileInstance
(Data, Size, FileID, ChangesetID)
SELECT Data, Size, %1, NULL
FROM FileInstance
WHERE FileID=%1
AND Sequence = (SELECT MAX(Sequence)
FROM FileInstance
WHERE FileID=%1);
通过删除子选择并用窗口函数替换它,select语句可能更快:
INSERT INTO FileInstance
(Data, Size, FileID, ChangesetID)
select Data, Size, fileID, NULL
from (
select data,
size,
fileid,
max(sequence) over (partition by fileId) as max_seq,
sequence
from fileinstance
where fileID = %1
) t
where sequence = max_seq;