[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
))

오류를 검색하고 mysql 다음 페이지 http://dev.mysql.com/doc/refman/5.1/en/subquery-restrictions.html 에서 찾았 지만 도움이되지 않습니다.

SQL 쿼리를 수정하려면 어떻게해야합니까?



답변

문제는 MySQL이 미친 이유가 무엇이든 다음과 같은 쿼리를 작성할 수 없다는 것입니다.

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

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


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

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

이로 인해 필요한 필드가 임시 테이블에 내재적으로 복사되므로 허용됩니다.

이 솔루션을 여기 에서 찾았 습니다 . 그 기사의 메모 :

SELECT * FROM table실제 쿼리에서는 하위 쿼리 만 수행하고 싶지 않습니다 . 예제를 단순하게 유지하고 싶었습니다. 실제로 가장 안쪽 쿼리에 필요한 열만 선택 WHERE하고 결과를 제한하기 위해 좋은 절을 추가해야합니다 .


답변

세 단계로이 작업을 수행 할 수 있습니다.

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


답변

MySQL에서는 동일한 테이블을 하위 쿼리하여 하나의 테이블을 업데이트 할 수 없습니다.

쿼리를 두 부분으로 분리하거나

 업데이트 TABLE_A AS A
 내부 조인 TABLE_A A에서 B로 A.field1 = B.field1
 SET field2 =? 


답변

하위 쿼리에서 임시 테이블 (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’열에 새로운 이름을 지정했습니다.


답변

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

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'
);

또는 유사합니다.


답변

BlueRaja가 게시 한 접근법은 느리게 테이블에서 중복을 삭제하는 데 사용하면서 수정했습니다. 큰 테이블을 가진 사람에게 도움이되는 경우 Original Query

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)


답변

참고로 Mysql 변수를 사용하여 임시 결과를 저장할 수도 있습니다.

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

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