Postgres使用SELECT命令INSERT INTO

Ste*_*eve 9 sql postgresql

通过select语句插入Postgres时,行保证是否按照select语句返回的顺序插入?

也就是说,给定一个表bar(where idis SERIAL PRIMARY KEYnameis TEXT):

id | name
---+-----
 0 | A
 1 | B
 2 | C
Run Code Online (Sandbox Code Playgroud)

另一个表foo(空和具有相同的模式),如果我INSERT INTO foo (name) SELECT name FROM bar ORDER BY id DESCfoo保证:

id | name
---+-----
 0 | C
 1 | B
 2 | A
Run Code Online (Sandbox Code Playgroud)

这似乎是这种情况,但我想确认它不是一个实现细节,可能不适用更大的选择.

我阅读了SQL-92标准中的第13.8节和一般规则#3声称"在将任何行插入B之前有效地评估了查询表达式",但它没有明确说明有关排序的内容.标准是否有目的地模糊(也许允许并行插入?)和排序是一个实现细节?

Ste*_*eve 6

我在 Postgres 邮件列表上询问过,他们对澄清有所帮助。事实证明,这是一个特定于数据库的答案,因此如果您正在阅读本文并使用不同的数据库,答案可能会有所不同。

从 9.6 开始,Postgres 将按照返回的结果集的顺序进行逻辑插入。

该行为在此提​​交中明确编码:https : //github.com/postgres/postgres/commit/9118d03a8cca3d97327c56bf89a72e328e454e63

从提交描述:

例如,在 SELECT x, nextval('seq') FROM tab ORDER BY x LIMIT 10; 可能希望 nextval() 值的顺序与 x 相同,并且 nextval() 的运行次数不超过 10 次。

过去,Postgres 在这方面是不一致的:如果排序是通过索引扫描执行的,您将获得理想的行为,但如果必须通过显式排序步骤完成,则不会。

tl;博士; 插入顺序是一个实现细节,但有目的地在 Postgres 9.6 及更高版本中编码以符合直觉。在 9.6 之前,没有任何保证。


Lau*_*lbe 5

新表中的行将按照子句指定的顺序插入ORDER BY,因此id从序列生成的结果将反映此顺序。

要验证这一点,请查看执行计划,您应该能够SortInsert.