[英]Assign sequential positions to thousands of records in PostgreSQL
Using Ruby on Rails —but hopefully this can be solved via PostgreSQL directly, I'm trying to move 100,000 items from one list to another, while assigning each of them a sequential position: 使用Ruby on Rails-但希望可以通过PostgreSQL直接解决,我试图将100,000个项目从一个列表移动到另一个列表,同时为每个列表分配一个顺序的位置:
List A (where position don't matter): 清单A(位置无关紧要):
- item 1, position: nil
- item 2, position: nil
- item 3, position: nil
List B (where positions do matter): 清单B(职位很重要):
- item 4, position: 1
And as a result, I want: 结果,我想要:
List B: 清单B:
- item 4, position: 1
- item 1, position: 2
- item 2, position: 3
- item 3, position: 4
Various strategies I've thought about so far: 到目前为止,我考虑过的各种策略:
I am not entirely sure what are you trying to do here, but I suspect that sequences would be the best option here (but not dynamically created ones, that almost always a bad idea). 我不确定您要在这里做什么,但是我怀疑序列是这里的最佳选择(但不是动态创建的序列,这几乎总是一个坏主意)。 If you really don't want to use sequences, you could also use window functions and specificaly the row_number windows function.
如果您确实不想使用序列,则还可以使用窗口函数 ,特别是row_number窗口函数。
Here's a complete example. 这是一个完整的例子。 Suppose that you have the following tables with some sample data:
假设您具有包含一些示例数据的下表:
CREATE TABLE ListA (
item integer NOT NULL,
position integer
);
CREATE TABLE ListB ( item integer NOT NULL, position integer ); CREATE TABLE ListB(项目整数NOT NULL,位置整数);
INSERT INTO ListA(item) VALUES (1),(2),(3);
INSERT INTO ListB(item,position) VALUES (4,1);
Then the following query returns all elements of ListA
but with a new position assigned to them (starting from 1): 然后,以下查询返回
ListA
所有元素,但是ListA
分配了新位置(从1开始):
SELECT item,row_number() OVER (ORDER BY item)
FROM ListA;
If you would like to start the position numbers from where ListB
stops, you can do it like that 如果您想从
ListB
停止的位置开始位置编号,则可以这样做
SELECT item,row_number() OVER (ORDER BY item)+(SELECT max(position) FROM ListB)
FROM ListA;
Finally, to add those rows to ListB
, you can do that like so: 最后,要将这些行添加到
ListB
,您可以像这样:
INSERT INTO ListB(item,position)
SELECT item,row_number() OVER (ORDER BY item)+(SELECT max(position) FROM ListB)
FROM ListA;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.