我的数据看起来大致如下:
user_id range start end
10 500 1 500
11 175
12 200
需要将其转换为以下内容:
user_id range start end
10 500 1 500
11 175 501 675
12 200 676 875
所以每个后续行的起始编号是前一行的结束编号。当前行的结束编号是起始编号+范围-1。
我试图纯粹在SQL中这样做,但似乎有点卡住,因为这会产生错误:
UPDATE users U
SET start = ( SELECT end+1 FROM users U2 WHERE U2.id = U.id - 1 )
WHERE U.id > 1;
导致You can't specify target table 'users' for update in FROM clause
- 当我还在寻找解决方案时,似乎无法找到解决方案。
答案 0 :(得分:1)
基本上,使用子查询
更改子查询部分(SELECT end+1 FROM (SELECT end, id FROM users) U2 WHERE U2.id = U.id - 1)
很脏,但它应该有效。如果您的表很大(并且取决于您的mysql服务器上的一些其他配置值),请注意它会慢,并且我不建议在生产代码上使用它。 此外,您已经掌握了所有后续用户ID,但可能并非如此。如果你的id上有间隙,它会在字段上设置为null,否则可能会失败。
如果您的ID存在空白,可以执行以下操作:
(SELECT end+1 FROM (SELECT end, id FROM users) U2 WHERE U2.id < U.id LIMIT 1)
答案 1 :(得分:1)
如果你有大表,那将是一个缓慢的查询,但你可以使用交叉连接来解决这个问题。
UPDATE users U CROSS JOIN users U2
SET U.start = U2.end WHERE U.id = U2.id - 1;
我可能会想到有一个额外的字段引用包含用于其起始值的结束值的记录。这将允许有效的自联接更新,并在您的自动增量中存在间隙时解决问题。查询可能看起来像
UPDATE users U INNER JOIN users U2 on U.prev_id = U2.id
SET U.start = U2.end;