You can't specify target table for update in FROM clause

前端 未结 11 1348
野趣味
野趣味 2020-11-21 22:46

I have a simple mysql table:

CREATE TABLE IF NOT EXISTS `pers` (
  `persID` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(35) NOT NULL,
  `gehalt` int(11         


        
相关标签:
11条回答
  • 2020-11-21 22:55

    Just as reference, you can also use Mysql Variables to save temporary results, e.g.:

    SET @v1 := (SELECT ... );
    UPDATE ... SET ... WHERE x=@v1;
    

    https://dev.mysql.com/doc/refman/5.7/en/user-variables.html

    0 讨论(0)
  • 2020-11-21 22:56

    It's quite simple. For example, instead of writing:

    INSERT INTO x (id, parent_id, code) VALUES (
        NULL,
        (SELECT id FROM x WHERE code='AAA'),
        'BBB'
    );
    

    you should write

    INSERT INTO x (id, parent_id, code)
    VALUES (
        NULL,
        (SELECT t.id FROM (SELECT id, code FROM x) t WHERE t.code='AAA'),
        'BBB'
    );
    

    or similar.

    0 讨论(0)
  • 2020-11-21 22:57

    MariaDB has lifted this starting from 10.3.x (both for DELETE and UPDATE):

    UPDATE - Statements With the Same Source and Target

    From MariaDB 10.3.2, UPDATE statements may have the same source and target.

    Until MariaDB 10.3.1, the following UPDATE statement would not work:

    UPDATE t1 SET c1=c1+1 WHERE c2=(SELECT MAX(c2) FROM t1);
      ERROR 1093 (HY000): Table 't1' is specified twice, 
      both as a target for 'UPDATE' and as a separate source for data
    

    From MariaDB 10.3.2, the statement executes successfully:

    UPDATE t1 SET c1=c1+1 WHERE c2=(SELECT MAX(c2) FROM t1);
    

    DELETE - Same Source and Target Table

    Until MariaDB 10.3.1, deleting from a table with the same source and target was not possible. From MariaDB 10.3.1, this is now possible. For example:

    DELETE FROM t1 WHERE c1 IN (SELECT b.c1 FROM t1 b WHERE b.c2=0);
    

    DBFiddle MariaDB 10.2 - Error

    DBFiddle MariaDB 10.3 - Success

    0 讨论(0)
  • 2020-11-21 22:59

    If you are trying to read fieldA from tableA and save it on fieldB on the same table, when fieldc = fieldd you might want consider this.

    UPDATE tableA,
        tableA AS tableA_1 
    SET 
        tableA.fieldB= tableA_1.filedA
    WHERE
        (((tableA.conditionFild) = 'condition')
            AND ((tableA.fieldc) = tableA_1.fieldd));
    

    Above code copies the value from fieldA to fieldB when condition-field met your condition. this also works in ADO (e.g access )

    source: tried myself

    0 讨论(0)
  • 2020-11-21 23:00

    The Approach posted by BlueRaja is slow I modified it as I was using to delete duplicates from the table. In case it helps anyone with large tables Original Query

    delete from table where id not in (select min(id) from table group by field 2)
    

    This is taking more time:

    DELETE FROM table where ID NOT IN(
      SELECT MIN(t.Id) from (select Id,field2 from table) AS t GROUP BY field2)
    

    Faster Solution

    DELETE FROM table where ID NOT IN(
       SELECT x.Id from (SELECT MIN(Id) as Id from table GROUP BY field2) AS t)
    
    0 讨论(0)
  • 2020-11-21 23:02

    Make a temporary table (tempP) from a subquery

    UPDATE pers P 
    SET P.gehalt = P.gehalt * 1.05 
    WHERE P.persID IN (
        SELECT tempP.tempId
        FROM (
            SELECT persID as tempId
            FROM pers P
            WHERE
                P.chefID IS NOT NULL OR gehalt < 
                    (SELECT (
                        SELECT MAX(gehalt * 1.05) 
                        FROM pers MA 
                        WHERE MA.chefID = MA.chefID) 
                        AS _pers
                    )
        ) AS tempP
    )
    

    I've introduced a separate name (alias) and give a new name to 'persID' column for temporary table

    0 讨论(0)
提交回复
热议问题