我有一张食物表。他们有一个"位置"表示他们应该在列表中显示的顺序的字段(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+ | ... | ... |
+------+----------+----------+------------+
我希望能够说"将梨移到筹码前#34;其中包括将Pears的位置设置为位置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 position
而且我会以正确的顺序获得所有食物。
是否可以使用单个查询执行此操作?请记住,记录可能在列表中向上或向下移动,并且该表包含多个列表的记录,因此我们需要隔离listID。
我对SQL的了解非常有限,所以我现在知道的唯一方法是SELECT id, position FROM mytable WHERE listID = 1 AND position BETWEEN 1 AND 5
然后我可以使用Javascript(node.js)将位置5更改为1,并增加所有其他+1。然后更新我刚刚更改的所有记录。
只是当我尝试阅读SQL内容时,每个人都在说避免多次查询并避免进行同步编码等等。
由于
答案 0 :(得分:1)
这需要一个更新许多记录的复杂查询。但是对数据进行一些小改动可以改变一些事情,这样就可以通过一个只修改一条记录的简单查询来实现。
UPDATE my_table set position = position*10;
在过去,许多系统上的BASIC编程语言都有行号,它鼓励了spagetti代码。许多人写了GOTO line_number
而不是函数。如果您按顺序对行进行编号并且必须添加或删除几行,则会出现真正的问题。人们是如何绕过它的?按增量线增加10!这就是我们在这里所做的。
所以你想让梨成为第二项吗?
UPDATE my_table set position = 15 WHERE listId=1 AND name = 'Pears'
担心多次重新排序后项目之间的间隙最终会消失吗?没有恐惧只是做
UPDATE my_table set position = position*10;
不时。
答案 1 :(得分:1)
我不认为这可以在少于两个查询中方便地完成,这是可以的,应该尽可能少的查询,但不是不惜任何代价。这两个查询就像(基于你自己写的)
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;
答案 2 :(得分:0)
我大多数都弄清楚了我的问题。所以我决定在这里给出一个答案,任何人都觉得它有用。 我可以在SQL中使用CASE语句。另外,通过使用Javascript预先构建我的SQL查询,我可以更改多个记录。
这构建了我的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;
如果我想将Pears移到Chips之前。我可以设置:
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