UPDATE语句的where子句中的子查询

han*_*man 4 mysql sql

我有ATM卡的数据库,其中有字段account_no,card_no,is_blocked,is_activated,issue_date字段帐号和卡号不唯一,因为旧卡将过期并标记为is_block = Y和另一个具有相同卡号的记录,帐号将插入到is_blocked = N的新行中.现在我需要在issue_date ie的帮助下更新is_blocked/is_activated

UPDATE card_info set is_blocked='Y' where card_no='6396163270002509' 
AND opening_date=(SELECT MAX(opening_date) FROM card_info WHERE card_no='6396163270002509')
Run Code Online (Sandbox Code Playgroud)

但是不允许我这样做它会引发跟随错误

1093 - You can't specify target table 'card_info' for update in FROM clause
Run Code Online (Sandbox Code Playgroud)

Mah*_*mal 5

试试这个:

UPDATE card_info ci
INNER JOIN 
(
  SELECT card_no, MAX(opening_date) MaxOpeningDate
  FROM card_info
  GROUP BY card_no
) cm ON ci.card_no = cm.card_no AND ci.opening_date = cm.MaxOpeningDate
SET ci.is_blocked='Y' 
WHERE ci.card_no = '6396163270002509' 
Run Code Online (Sandbox Code Playgroud)


a_h*_*ame 5

这是MySQL解析器的愚蠢限制之一。解决此问题的常用方法是使用Mahmoud所示的JOIN查询。

(至少对我来说)令人惊讶的部分是,它确实确实是解析器问题,而不是引擎本身的问题,因为如果将子选择包装到派生表中,则可以正常工作:

UPDATE card_info 
   SET is_blocked='Y' 
 WHERE card_no = '6396163270002509' 
 AND opening_date = ( select max_date 
                      from (
                          SELECT MAX(opening_date) as_max_date 
                          FROM card_info 
                          WHERE card_no='6396163270002509') t
                    )
Run Code Online (Sandbox Code Playgroud)