복붙노트

[SQL] 당신은 FROM 절에 업데이트를 목표 테이블을 지정할 수 없습니다

SQL

당신은 FROM 절에 업데이트를 목표 테이블을 지정할 수 없습니다

나는 간단한 MySQL의 테이블을 가지고 :

CREATE TABLE IF NOT EXISTS `pers` (
  `persID` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(35) NOT NULL,
  `gehalt` int(11) NOT NULL,
  `chefID` int(11) DEFAULT NULL,
  PRIMARY KEY (`persID`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=4 ;

INSERT INTO `pers` (`persID`, `name`, `gehalt`, `chefID`) VALUES
(1, 'blb', 1000, 3),
(2, 'as', 1000, 3),
(3, 'chef', 1040, NULL);

나는 갱신 다음 실행했지만, 난 단지 오류 1093 수 :

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

나는 오류 검색 및 페이지 http://dev.mysql.com/doc/refman/5.1/en/subquery-restrictions.html 다음 MySQL의에서 찾았지만 그것은 나에게 도움이되지 않습니다.

나는 SQL 쿼리를 해결하기 위해 무엇을 할 것인가?

해결법

  1. ==============================

    1.문제는 MySQL이, 어리석은 어떤 이유로,이 같은 쓰기 쿼리를 허용하지 않는다는 것입니다 :

    문제는 MySQL이, 어리석은 어떤 이유로,이 같은 쓰기 쿼리를 허용하지 않는다는 것입니다 :

    UPDATE myTable
    SET myTable.A =
    (
        SELECT B
        FROM myTable
        INNER JOIN ...
    )
    

    당신이 UPDATE를 수행하는 경우 즉, / INSERT은 / 테이블에 DELETE, 당신은 (... 당신은 그러나 그 외부 테이블에서 필드를 참조 할 수 있습니다) 내부 쿼리에서 해당 테이블을 참조 할 수 없습니다

    용액을 다음과 같이, (myTable에 FROM SELECT *)가 서브 myTable에 쿼리의 인스턴스를 대체하는 것이다

    UPDATE myTable
    SET myTable.A =
    (
        SELECT B
        FROM (SELECT * FROM myTable) AS something
        INNER JOIN ...
    )
    

    이것은 분명히 필요한 필드가 암시 적으로 임시 테이블에 복사되도록, 그래서 허용합니다.

    내가 여기에이 솔루션을 발견했다. 그 기사에서 참고 :

  2. ==============================

    2.당신은 세 단계로이 작업을 할 수 있습니다 :

    당신은 세 단계로이 작업을 할 수 있습니다 :

    CREATE TABLE test2 AS
    SELECT PersId 
    FROM pers p
    WHERE (
      chefID IS NOT NULL 
      OR gehalt < (
        SELECT MAX (
          gehalt * 1.05
        )
        FROM pers MA
        WHERE MA.chefID = p.chefID
      )
    )
    

    ...

    UPDATE pers P
    SET P.gehalt = P.gehalt * 1.05
    WHERE PersId
    IN (
      SELECT PersId
      FROM test2
    )
    DROP TABLE test2;
    

    또는

    UPDATE Pers P, (
      SELECT PersId
      FROM pers p
      WHERE (
       chefID IS NOT NULL 
       OR gehalt < (
         SELECT MAX (
           gehalt * 1.05
         )
         FROM pers MA
         WHERE MA.chefID = p.chefID
       )
     )
    ) t
    SET P.gehalt = P.gehalt * 1.05
    WHERE p.PersId = t.PersId
    
  3. ==============================

    3.MySQL은, 당신은 하위 쿼리 같은 테이블에서 하나 개의 테이블을 업데이트 할 수 없습니다.

    MySQL은, 당신은 하위 쿼리 같은 테이블에서 하나 개의 테이블을 업데이트 할 수 없습니다.

    당신은 두 부분으로 쿼리를 분리, 또는 할 수있는

     UPDATE TABLE_A AS A
     INNER JOIN TABLE_A AS B ON A.field1 = B.field1
     SET field2 = ? 
  4. ==============================

    4.하위 쿼리에서 임시 테이블 (tempP를) 확인

    하위 쿼리에서 임시 테이블 (tempP를) 확인

    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
    )
    

    나는 별도의 이름 (별명)을 도입하고 임시 테이블을위한 'persID'칼럼에 새로운 이름을 부여했습니다

  5. ==============================

    5.그것은 아주 간단합니다. 예를 들어, 쓰는 대신 :

    그것은 아주 간단합니다. 예를 들어, 쓰는 대신 :

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

    당신이 작성해야

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

    또는 이와 유사한.

  6. ==============================

    6.BlueRaja에 의해 게시 접근 방식은 느린 내가로 수정 나는 테이블에서 중복을 제거하기 위해 사용되었다. 경우는 대형 테이블을 가진 사람을 도움 원래 쿼리

    BlueRaja에 의해 게시 접근 방식은 느린 내가로 수정 나는 테이블에서 중복을 제거하기 위해 사용되었다. 경우는 대형 테이블을 가진 사람을 도움 원래 쿼리

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

    이것은 더 많은 시간을 가지고있다 :

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

    빠른 솔루션

    DELETE FROM table where ID NOT IN(
       SELECT x.Id from (SELECT MIN(Id) as Id from table GROUP BY field2) AS t)
    
  7. ==============================

    7.그냥 참고로, 당신은 또한, 예컨대을 임시 결과를 저장하기 위해 MySQL의 변수를 사용할 수 있습니다 :

    그냥 참고로, 당신은 또한, 예컨대을 임시 결과를 저장하기 위해 MySQL의 변수를 사용할 수 있습니다 :

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

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

  8. ==============================

    8.당신이 TABLEA에서 fieldA를 읽고 같은 테이블에 필드에 저장하려는 경우, 필드 = 필드 당신이 할 수 있습니다 때를 고려한다.

    당신이 TABLEA에서 fieldA를 읽고 같은 테이블에 필드에 저장하려는 경우, 필드 = 필드 당신이 할 수 있습니다 때를 고려한다.

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

    위의 코드를 복사 조건 필드가 조건을 충족 필드 필드의 값. 이것은 또한 ADO에서 작동 (예를 들어, 액세스)

    소스 : 자신을 시도

  9. ==============================

    9.MariaDB는 10.3.x에서 (DELETE 및 UPDATE 모두)에서이 시작을 해제했다 :

    MariaDB는 10.3.x에서 (DELETE 및 UPDATE 모두)에서이 시작을 해제했다 :

    DBFiddle MariaDB 10.2 - 오류

    DBFiddle MariaDB 10.3 - 성공

  10. ==============================

    10.다른 해결 방법은 이러한 구체화에 미치는 영향과 같이 명시 아니지만, 서브 쿼리에서 SELECT가 DISTINCT 또는 LIMIT 사용 등이 있습니다. 이 날 위해 일했습니다

    다른 해결 방법은 이러한 구체화에 미치는 영향과 같이 명시 아니지만, 서브 쿼리에서 SELECT가 DISTINCT 또는 LIMIT 사용 등이 있습니다. 이 날 위해 일했습니다

    MySQL의 문서에 언급 된

  11. from https://stackoverflow.com/questions/4429319/you-cant-specify-target-table-for-update-in-from-clause by cc-by-sa and MIT license