使用复杂的Predicas从表中更新数据

时间:2011-06-20 09:51:04

标签: sql tsql

我有TableAA1A2)和TableBB1B2) 假设

TableA
(1,x)
(1,y)
(1,z)
(2,e)

TableB
(1,xx)
(1,yy)
(1,xx)
(3,ff)

我想用TableA.A2列更新TableB.B2 我怎么能这样做

UPDATE TableA
SET A2 = B2
From TableA join TableB on A1=B1

不能正常工作 结果是:

TableA
(1,xx)
(1,xx)
(1,xx)
(2,e)

我正在寻找的结果是:

TableA
(1,xx)
(1,yy)
(1,xx)
(2,e)

4 个答案:

答案 0 :(得分:1)

;with cteB as
(
  select *,
         row_number() over(partition by B1 order by (select 1)) as rn
  from TableB
),
cteA as
(
  select *,
         row_number() over(partition by A1 order by (select 1)) as rn
  from TableA
)
update A set
  A2 = B.B2
from cteA as A
  inner join cteB as B
    on A.A1 = B.B1 and
       A.rn = B.rn

这将为您的样本数据和表结构生成所需的输出。但正如其他人所说,正如@Dems在评论中指出的那样,你无法控制更新的行。此更新语句将在每次运行时创建更新所需的密钥,并且由于order by子句为select 1,因此每次运行之间的更新顺序可能不同。

答案 1 :(得分:0)

看起来您的UPDATE可能正确,但您的数据不正确。

两个表在两个记录的第一个字段中都有1。这意味着当您将两个表连接在一起时,第一个表中的每个记录都匹配第二个表中的两个记录。

您的意思是在第一条记录中有1,在第二条记录中有2吗?

修改

扩展Damien提到的内容,您需要更改连接,以便TableB中只有一条记录与TableA中的每条记录匹配。你如何做到这一点取决于你想要达到的目标。基于示例数据的示例...

UPDATE
  TableA
SET
  B1 = TableB.B1
FROM
  TableA
INNER JOIN
  TableB
    ON  TableA.A1 = TableB.A1
    AND LEFT(TableA.B1, 1) = LEFT(TableB.B1, 1)

仅在连接中使用A1是不够的,但我也猜测你不想在连接中使用B1。

在这种情况下,您需要向表中添加另一个字段。某些类型的信息可以用来表示“TableA中的这条记录与TableB中的那条记录匹配”。

只有当您的数据和查询明确说明一对一的关系时,您才能获得所需的结果。所以这是一个问题:
- 如何知道TableB中的哪条记录需要复制到TableA中的哪条记录?


修改

感谢您的编辑。不幸的是,它没有改变任何东西:SQL表没有“自然”顺序。

虽然你可能已经按照这个顺序插入了数据,但也许它通常会在选择时回复,但不能保证。没有办法说“将TableA的第一条记录与TableB的第一条记录联系起来”,因为订单没有保证,因此“第一”意味着什么。

必须,我担心,会为每个表添加一个额外的列。如果您可以编写SELECT * FROM TableA ORDER BY NewColumn(s),并按照您想要的顺序获取数据,则可以解决。如果你不能用ORDER BY做到这一点,就不可能以一种总是将相同的值放在相同记录上的方式解决。

答案 2 :(得分:0)

如果您的连接颜色具有唯一记录:

UPDATE
    TableA
SET
a2 = (select TableB.b2 from TableB where TableA.a1=TableB.b1)
WHERE EXISTS
(select TableB.b2 from TableB where  TableA.a1=TableB.b1)

答案 3 :(得分:0)

您更新的示例没有帮助。你说你有TableB:

(1,xx)
(1,yy)
(1,xx)
(3,ff)

但是,你真的不喜欢。就SQL而言,这与:

相同
(1,xx)
(1,xx)
(1,yy)
(3,ff)

或:

(1,yy)
(1,xx)
(1,xx)
(3,ff)

甚至:

(1,yy)
(1,xx)
(3,ff)
(1,xx)

也就是说,行没有任何排序。您需要此表(和TableA)中的其他一些列,以允许一个表中的行与另一个表中的行唯一匹配。