2

我不太确定我是否以错误的方式思考这个问题,所以如果是这样的话,也许有人会指出我正确的方向。但是,如果我只是错过了这个概念,那么也许我可以得到帮助。

所以无论如何我都会赢……什么的。

我想做的是这样的,给定数据库中的一个表,在单个查询中将特定值移动到另一行。

为了澄清,以这张表为例:

id I value
0 I 5
1 I 2

我想移动id=0的,以便表格变为:

id I value
0 I 0
1 I 5

(注意!id=1的值无关紧要,它被覆盖并且id=0 _value_ 只是设置为零)

到目前为止,我的尝试是一个类似于以下内容的查询:

UPDATE atable 
SET item = CASE id 
WHEN '1' THEN (SELECT value FROM atable WHERE id='1') 
WHEN '0' THEN '0' 
END;

但是,这是无效的,我不能以这种方式使用SELECT。所以我的看法#2是:

UPDATE atable 
SET item=(SELECT value FROM atable WHERE id='1') 
WHERE id='0';

哪种有效,但是我找不到为id=0设置value=0的方法

我希望这一切都有意义,而不是现在只是漫无边际。

只是为了弄清楚: 我想值从一行移动到另一行,所以复制行不通,我可以弄清楚那个。而且我想在一个查询中完成,当然我可以将它分成两个查询,这很简单

感谢您花时间阅读本文。

4

4 回答 4

2

我认为这会有所帮助-

UPDATE atable a,
(SELECT value, id FROM atable) c
SET a.value = c.value 
WHERE a.id < @MAX(id)
AND a.id = c.id + 1;

唯一的条件是 id 应该按顺序排列,并且您不应该激活安全更新模式。

于 2012-05-21T21:43:17.577 回答
1

您可以通过一个查询来执行此操作,但只有当 ID 预计是连续的时才有可能

update a set a.value=isnull(b.value,0) from atable a left outer join atable b on a.id=b.id+1

编辑

update a set a.value=ifnull(b.value,0) from atable a left outer join atable b on a.id=b.id+1
于 2012-05-21T21:35:39.437 回答
1

这种类型的事情通常在事务中执行,以使其表现为原子操作。例如:

start transaction;    
set @myval = (select value from atable where id = 0);
update atable set value = @myval where id = 1;
update atable set value = 0 where id = 0;
commit;

可以使用单个语句将值从第一行“移动”到另一行,但是它看起来非常难看并且可能效率较低。我认为以下可能会这样做,但我认为这不是一个好主意。

update atable set value = 
      (select x.value from 
            (select value from atable where id = 0) x) 
   where id = 1;
于 2012-05-21T21:28:47.543 回答
0

我相信我会采用“简单”的解决方案,因为我确实有更多关于我不认为需要动态阅读的问题的信息。

因此,对于我的特定问题,我决定像这样解决它:

我有这些参数(在 php 中):

$fromSlot, $toSlot, $itemID

我想$itemID从一个插槽移动到另一个插槽。

但由于我知道项目的 id,我不妨将其插入到$toSlot并将项目设置$fromSlot为零。

基本上,该表有一个slotID, itemIDwhereslotID是唯一键,并且itemID是一个用于引用该插槽中项目的 id。

我的查询变成了:

UPDATE `slots` SET item = CASE slotID
WHEN '$fromSlot' THEN '0'
WHEN '$toSlot' THEN '$itemID'
END;

这样我就不必担心它可能首先将 设置$fromSlot为零,然后将该零“复制”到$toSlot.

我想避免将$itemID所有内容一起发送,但意识到这确实不是一个大问题,因为我宁愿避免进行两个查询然后发送额外的参数。

我想的另一种选择是跳过发送$itemID,然后首先更新$toSlotwithUPDATE slots SET item = (SELECT item FROM slots WHERE slotID='$fromSlot')然后第二个查询来设置$fromSlot.item

这就是我将如何解决它。

当然欢迎任何切肉刀的想法或诸如此类的东西,但我会将其标记为我接受的答案。

如果没有别的,也许它可以帮助人们遵循我的思路并理解我为什么问(并回答-_-)这个问题。

于 2012-05-22T08:02:00.630 回答