使用SQL根据单个logging的更改更改多个logging

我有一张食物的桌子。 他们有一个“职位”字段,表示他们应该在列表中显示的顺序(listID是他们所在的列表,我们不想重新排列另一个列表上的项目)。

+--id--+--listID--+---name---+--position--+ | 1 | 1 | cheese | 0 | | 2 | 1 | chips | 1 | | 3 | 1 | bacon | 2 | | 4 | 1 | apples | 3 | | 5 | 1 | pears | 4 | | 6 | 1 | pie | 5 | | 7 | 2 | carrots | 0 | | 8,9+ | 3,4+ | ... | ... | +------+----------+----------+------------+ 

我想能够说“移动梨前芯片”,其中包括梨的位置设置为1,然后递增其间的所有位置1,以便我的结果表看起来像这样…

 +--id--+--listID--+---name---+--position--+ | 1 | 1 | cheese | 0 | | 2 | 1 | chips | 2 | | 3 | 1 | bacon | 3 | | 4 | 1 | apples | 4 | | 5 | 1 | pears | 1 | | 6 | 1 | pie | 5 | | 7 | 2 | carrots | 0 | | 8,9+ | 3,4+ | ... | ... | +------+----------+----------+------------+ 

所以我需要做的就是SELECT name FROM mytable WHERE listID = 1 ORDER BY positionSELECT name FROM mytable WHERE listID = 1 ORDER BY position ,我会按正确的顺序得到我所有的食物。

是否有可能做到这一点与单一的查询? 请记住,logging可能在列表中向上或向下移动,并且该表包含多个列表的logging,所以我们需要隔离listID。

我的SQL知识是相当有限的,所以现在我知道这样做的唯一方法是SELECT id, position FROM mytable WHERE listID = 1 AND position BETWEEN 1 AND 5然后我可以使用Javascript(node.js)来改变位置5到1,并增加所有其他+1。 然后更新我刚刚更改的所有logging。

只要我试着阅读大家一直说的SQL东西,以避免多个查询,并避免做同步编码和类似的东西。

谢谢

这需要一个更新许多logging的复杂查询。 但是对数据的小改动可以改变事情,这样只需修改一条logging就可以实现。

 UPDATE my_table set position = position*10; 

在过去,许多系统上的BASIC编程语言都有行号,它鼓励使用spagetti代码。 很多人写了GOTO line_number而不是function。 如果您按顺序对行进行编号,并且必须添加或删除几行,则会出现真正的麻烦。 人们是如何绕过它的? 通过增加10行! 这就是我们在这里所做的。

所以你想让梨成为第二个项目?

 UPDATE my_table set position = 15 WHERE listId=1 AND name = 'Pears' 

担心最终的项目之间的差距将消失后多次重新sorting? 没有恐惧只是做

 UPDATE my_table set position = position*10; 

时。

我不认为这可以方便地完成在less于两个查询,这是可以的,应该有尽可能less的查询,但不是在任何代价。 这两个查询就像(根据你自己写的)

 UPDATE mytable SET position = 1 WHERE listID = 1 AND name = 'pears'; UPDATE mytable SET position = position + 1 WHERE listID = 1 AND position BETWEEN 2 AND 4; 

我主要是想出了我的问题。 所以我决定在这里提供一个答案,任何人认为它有帮助。 我可以在SQL中使用CASE语句。 另外通过使用Javascript预先构build我的SQL查询,我可以更改多个logging。

这生成我的SQL查询:

 var sql; var incrementDirection = (startPos > endPos)? 1 : -1; sql = "UPDATE mytable SET position = CASE WHEN position = "+startPos+" THEN "+endPos; for(var i=endPos; i!=startPos; i+=incrementDirection){ sql += " WHEN position = "+i+" THEN "+(i+incrementDirection); } sql += " ELSE position END WHERE listID = "+listID; 

如果我想把梨移动到芯片之前。 我可以设置:

 startPos = 4; endPos = 1; listID = 1; 

我的代码将产生一个如下所示的SQL语句:

 UPDATE mytable SET position = CASE WHEN position = 4 THEN 1 WHEN position = 1 THEN 2 WHEN position = 2 THEN 3 WHEN position = 3 THEN 4 ELSE position END WHERE listID = 1 

我运行该代码,我的决赛桌将如下所示:

 +--id--+--listID--+---name---+--position--+ | 1 | 1 | cheese | 0 | | 2 | 1 | chips | 2 | | 3 | 1 | bacon | 3 | | 4 | 1 | apples | 4 | | 5 | 1 | pears | 1 | | 6 | 1 | pie | 5 | | 7 | 2 | carrots | 0 | | 8,9+ | 3,4+ | ... | ... | +------+----------+----------+------------+ 

之后,我所要做的就是运行SELECT name FROM mytable WHERE listID = 1 ORDER BY position ,输出如下:

 cheese pears chips bacon apples pie