基于SQL

时间:2016-11-16 02:32:47

标签: mysql node.js

我有一张食物表。他们有一个"位置"表示他们应该在列表中显示的顺序的字段(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内容时,每个人都在说避免多次查询并避免进行同步编码等等。

由于

3 个答案:

答案 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