我有TableA
(A1
,A2
)和TableB
(B1
,B2
)
假设
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)
答案 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)中的其他一些列,以允许一个表中的行与另一个表中的行唯一匹配。