UPDATE 语句在子查询中使用相同的 table

UPDATE statement using the same table in subquery

SELECT
    vl1.phone_number,
    vl1.first_name,
    CONCAT(
        SUBSTRING(
            (
            SELECT
                vl2.phone_number 
            FROM
                list as vl2
            WHERE
                vl2.phone_number LIKE CONCAT( SUBSTRING( vl1.phone_number FROM 1 FOR 3 ), "%" ) 
            ORDER BY
                RAND( ) 
                LIMIT 1 
            ) 
        FROM
            1 FOR 6 
        ),
        FLOOR( RAND( ) * ( 8999 ) ) + 1000 
    ) AS autogenNumber 
FROM
    list as vl1
LIMIT 1

我得到的结果是

phone_number | firstname | autogenNumber

autogenNumber 是通过首先搜索共享前三位数字的其他号码生成的。然后从该号码中选取 6 位数字,并将另外 4 位随机数字替换到末尾。

上面的 sql 查询完全按照我的需要生成了 autogen 编号。

但是,当我想使用下面的类似查询更新此列表中的列 security_phrase 时,问题就出现了。

UPDATE list as vl1
SET vl1.security_phrase = (
    CONCAT(
        SUBSTRING(
            (
                SELECT
                    vl2.phone_number 
                FROM
                    list AS vl2 
                WHERE
                    vl2.phone_number LIKE CONCAT( SUBSTRING(phone_number FROM 1 FOR 3 ), "%" ) 
                ORDER BY
                    RAND( ) 
                    LIMIT 1 
                ) 
            FROM
                1 FOR 6 
            ),
            FLOOR( RAND( ) * ( 8999 ) ) + 1000 
        ) 
    ) 
    LIMIT 10

给我一个错误:

1093 - Table 'vl1' is specified twice, both as a target for 'UPDATE' and as a separate source for data

我也试过了

UPDATE list AS vl1
JOIN list AS vl2 

SET vl1.security_phrase = (
    CONCAT( SUBSTRING( vl2.phone_number FROM 1 FOR 6 ), FLOOR( RAND( ) * ( 8999 ) ) + 1000 ) 
) 
WHERE
    vl2.phone_number LIKE CONCAT( SUBSTRING( vl1.phone_number FROM 1 FOR 3 ), "%" ) 

不工作,没有给出预期的结果...

任何帮助

MySQL 不允许在另一个子查询中再次引用 table 正在更新除非FROM 子句内 (Derived Table).

现在,在您的特定情况下,我们需要将完整的 SELECT 查询块作为派生 Table。正如在聊天中讨论的那样,lead_id 是您的主键,因此我们将使用 PK 重新加入以相应地更新行。

UPDATE list AS t1 
JOIN 
(
  SELECT
    vl1.lead_id,
    CONCAT(
        SUBSTRING(
            (
            SELECT
                vl2.phone_number 
            FROM
                list as vl2
            WHERE
                vl2.phone_number LIKE CONCAT( SUBSTRING( vl1.phone_number FROM 1 FOR 3 ), "%" ) 
            ORDER BY
                RAND( ) 
                LIMIT 1 
            ) 
        FROM
            1 FOR 6 
        ),
        FLOOR( RAND( ) * ( 8999 ) ) + 1000 
    ) AS autogenNumber 
  FROM
    list as vl1
) AS dt 
  ON dt.lead_id = t1.lead_id 
SET t1.security_phrase = dt.autogenNumber