UPDATE
table1 alias1
,table2 alias2
SET
alias2.CURRENT_CD_BALANCE = alias2.CURRENT_CD_BALANCE - alias1.ORIGINAL_AMOUNT
,alias1.COMMENT = concat('Sum of ',alias1.ORIGINAL_AMOUNT,' Cancelled')
,alias1.BALANCE = 0
,alias1.ORIGINAL_AMOUNT = 0
,TRAN_TYPE = 'D'
WHERE
alias1.STORE_ID = alias2.STORE_ID
AND alias1.ACCTNO = alias2.ACCTNO
AND alias1.AR_TRANS_ID = value1;
Query OK, 1 row affected (0.001 sec) Rows matched: 2 Changed: 1 Warnings: 0
在运行上述查询之前alias1.ORIGINAL_AMOUNT is 900000
和alias2.CURRENT_CD_BALANCE is the 900000.
运行查询后,tabel1.ORIGINAL_AMOUNT
设置为零,但alias2.CURRENT_CD_BALANCE
不变(值仍为900000)。
这意味着在执行操作'alias2.CURRENT_CD_BALANCE = alias2.CURRENT_CD_BALANCE - alias1.ORIGINAL_AMOUNT'
之前将alias1.ORIGINAL_AMOUNT
设置为零。
但是,alias1.COMMMENT
列的值为'Sum of 900000 Cancelled'
,这表明alias1.ORIGINAL_AMOUNT
的初始值在被设置为零之前被分配给了alias1.COMMENT。
为什么会这样呢?
应该如何构造此查询,以便在将alias2.CURRENT_CD_BALANCE
设置为零之前从alias2.CURRENT_CD_BALANCE
中减去alias1.ORIGINAL_AMOUNT
的初始值?
服务器的响应表明这两个表是
我试过使用不带别名的连接来重构查询,组合(STORE_ID,ACCTNO)在两个表上都是唯一的键,AR_TRANS_ID也是唯一的。
2条答案
按热度按时间fquxozlt1#
多表UPDATE中的赋值顺序是不确定的,SET子句中的赋值表达式以不确定的顺序执行。
如果要确定地执行此操作,则必须使用源表的两个副本。第一个副本用于更新,另一个副本提供更新数据。大多数情况下,更新数据可以在子查询中获取,这比使用两个单独的表更理想。
即,代替非确定性
你会用
qyswt5oh2#
来自(文件):
单表UPDATE赋值通常从左到右计算。对于多表更新,不能保证赋值按任何特定顺序执行。
我不得不对结构进行一些猜测,但这足以重现你所看到的:
通过颠倒连接中表的顺序,我观察到了预期的行为:
db<>fiddle
考虑到上面引用的MySQL文档,我不确定依赖它是否合适。
我不能100%确定您要达到的目的,但它似乎是某种财务交易的冲销和相关摘要的更新。通常,交易历史记录应视为不可更改,任何更改都必须作为新交易应用,而不是对现有交易的修订。