programing

MySQL Error 1093 - FROM 절에서 업데이트할 대상 테이블을 지정할 수 없습니다.

itsource 2022. 10. 4. 21:57
반응형

MySQL Error 1093 - FROM 절에서 업데이트할 대상 테이블을 지정할 수 없습니다.

story_category데이터베이스에 있는 엔트리가 파손되어 있습니다.다음 쿼리는 파손된 엔트리를 반환합니다.

SELECT * 
FROM  story_category 
WHERE category_id NOT IN (
    SELECT DISTINCT category.id 
    FROM category INNER JOIN 
       story_category ON category_id=category.id);

다음을 실행하고 있는 파일을 삭제하려고 했습니다.

DELETE FROM story_category 
WHERE category_id NOT IN (
    SELECT DISTINCT category.id 
    FROM category 
      INNER JOIN story_category ON category_id=category.id);

하지만 다음 오류가 발생합니다.

#1093 - FROM 절에서 업데이트 대상 테이블 'story_category'를 지정할 수 없습니다.

어떻게 극복해야 할까요?

업데이트: 이 답변에는 일반적인 오류 분류가 포함됩니다.OP의 정확한 쿼리를 가장 잘 처리하는 방법에 대한 자세한 답변은 이 질문에 대한 다른 답변을 참조하십시오.

MySQL에서는 SELECT 부분에서 사용하는 것과 동일한 테이블을 수정할 수 없습니다.
이 동작에 대해서는http://http://dev.mysql.com/doc/refman/5.6/en/update.html 를 참조해 주세요.

그냥 테이블에 앉으면 되지 않을까?

쿼리의 쉐이핑을 변경할 수 있을 정도로 논리가 단순할 경우 적절한 선택 기준을 사용하여 서브쿼리가 손실되고 테이블 자체가 결합됩니다.이로 인해 MySQL은 테이블을 두 가지 다른 것으로 보고 파괴적인 변경을 계속할 수 있습니다.

UPDATE tbl AS a
INNER JOIN tbl AS b ON ....
SET a.col = b.col

또는 하위 쿼리를 from 구에 더 깊이 중첩해 보십시오.

서브쿼리가 꼭 필요한 경우 회피책이 있지만 성능 등 여러 가지 이유로 인해 문제가 발생합니다.

UPDATE tbl SET col = (
  SELECT ... FROM (SELECT.... FROM) AS x);

FROM 절의 중첩된 하위 쿼리는 암묵적인 임시 테이블을 생성하므로 업데이트할 테이블과 동일한 테이블로 계산되지 않습니다.

...하지만 쿼리 옵티마이저를 조심하십시오.

그러나 MySQL 5.7.6 이후부터는 옵티마이저가 서브쿼리를 최적화해도 오류가 발생할 수 있습니다.운 좋게도optimizer_switch변수를 사용하여 이 동작을 끌 수 있습니다.단, 단기적인 수정이나 소규모 일회성 태스크에 대해서는 권장할 수 없습니다.

SET optimizer_switch = 'derived_merge=off';

피터 5세 덕분이다. 코멘트에서 이 조언에 대해 Mörch.

예시는 원래 Nabble에서 출판된 Baron Schwartz의 기술로, 여기에서 바꿔 표현하고 확장했습니다.

NexusRex는 같은 테이블에서 join을 사용하여 삭제하기 위한 매우 좋은 솔루션을 제공했습니다.

이렇게 하면:

DELETE FROM story_category
WHERE category_id NOT IN (
        SELECT DISTINCT category.id AS cid FROM category 
        INNER JOIN story_category ON category_id=category.id
)

에러가 납니다.

그러나 조건을 하나 더 선택할 경우:

DELETE FROM story_category
WHERE category_id NOT IN (
    SELECT cid FROM (
        SELECT DISTINCT category.id AS cid FROM category 
        INNER JOIN story_category ON category_id=category.id
    ) AS c
)

옳은 일을 할 수 있을 거야!!

설명:쿼리 옵티마이저는 첫 번째 쿼리에 대해 파생된 병합 최적화를 수행하지만(오류로 인해 실패함), 두 번째 쿼리는 파생된 병합 최적화에 적합하지 않습니다.따라서 옵티마이저는 먼저 서브쿼리를 실행하도록 강제됩니다.

inner join요요없없없없다다 것 요.story_category서, 「」는category_id is is is is 。categorytable.syslog를 클릭합니다.

그 대신:

DELETE FROM story_category 
WHERE category_id NOT IN (
    SELECT DISTINCT category.id 
    FROM category INNER JOIN
         story_category ON category_id=category.id);

다음을 수행합니다.

DELETE FROM story_category 
WHERE category_id NOT IN (
    SELECT DISTINCT category.id 
    FROM category);

최근 같은 테이블에서 다음과 같이 레코드를 업데이트해야 했습니다.

UPDATE skills AS s, (SELECT id  FROM skills WHERE type = 'Programming') AS p
SET s.type = 'Development' 
WHERE s.id = p.id;

할 수 없다면

UPDATE table SET a=value WHERE x IN
    (SELECT x FROM table WHERE condition);

같은 테이블이기 때문에 트릭을 사용하여 다음과 같이 할 수 있습니다.

UPDATE table SET a=value WHERE x IN
    (SELECT * FROM (SELECT x FROM table WHERE condition) as t)

[갱신, 삭제 등]

DELETE FROM story_category
WHERE category_id NOT IN (
    SELECT cid FROM (
        SELECT DISTINCT category.id AS cid FROM category INNER JOIN story_category ON category_id=category.id
    ) AS c
)

OP가 달성하려고 하는 특정 쿼리에 대해 가장 이상적이고 효율적인 방법은 서브쿼리를 전혀 사용하지 않는 것입니다.

여기 있습니다.LEFT JOINOP:

SELECT s.* 
FROM story_category s 
LEFT JOIN category c 
ON c.id=s.category_id 
WHERE c.id IS NULL;

★★★★★★DELETE s는 삭제 을 「삭제」로합니다.story_categorytable.syslog를 클릭합니다.
»

DELETE s 
FROM story_category s 
LEFT JOIN category c 
ON c.id=s.category_id 
WHERE c.id IS NULL;

같은 테이블의 서브쿼리를 사용하여 Priority 열 값이 >=1이면 Priority 열 값을 1로 업데이트하여 적어도1개의 행에 Priority=1이 포함되어 있는지 확인합니다(업데이트 실행 중에 확인해야 하는 조건이었기 때문에).


UPDATE My_Table
SET Priority=Priority + 1
WHERE Priority >= 1
AND (SELECT TRUE FROM (SELECT * FROM My_Table WHERE Priority=1 LIMIT 1) as t);

좀 못생긴 건 알지만 잘 작동해요.

가장 간단한 방법은 서브쿼리 내에서 부모쿼리 테이블을 참조할 때 테이블에일리어스를 사용하는 것입니다.

예:

insert into xxx_tab (trans_id) values ((select max(trans_id)+1 from xxx_tab));

변경 내용:

insert into xxx_tab (trans_id) values ((select max(P.trans_id)+1 from xxx_tab P));

원하는 행의 ID를 임시 테이블에 삽입한 다음 해당 테이블에 있는 모든 행을 삭제할 수 있습니다.

@Cheekysoft가 두 단계로 진행한다는 것은 어떤 의미인지도 모릅니다.

@CheekySoft가 링크한Mysql UPDATE Syntax에 따르면 맨 아래쪽에 표시되어 있습니다.

현재 테이블을 업데이트하고 하위 쿼리의 동일한 테이블에서 선택할 수 없습니다.

유니온에서 store_category를 선택하면서 store_category에서 삭제 중이신 것 같습니다.

Select 스테이트먼트의 결과를 별도의 변수에 저장한 후 삭제 쿼리에 사용합니다.

이거 먹어봐

DELETE FROM story_category 
WHERE category_id NOT IN (
SELECT DISTINCT category.id 
FROM (SELECT * FROM STORY_CATEGORY) sc;

뭔가가 작동하지 않을 경우, 정문을 통해 들어올 때 후문을 이용하십시오.

drop table if exists apples;
create table if not exists apples(variety char(10) primary key, price int);

insert into apples values('fuji', 5), ('gala', 6);

drop table if exists apples_new;
create table if not exists apples_new like apples;
insert into apples_new select * from apples;

update apples_new
    set price = (select price from apples where variety = 'gala')
    where variety = 'fuji';
rename table apples to apples_orig;
rename table apples_new to apples;
drop table apples_orig;

빠르다.데이터가 클수록 좋습니다.

이 질문이 도움이 되길 바랍니다.

DELETE FROM story_category LEFT JOIN (SELECT category.id FROM category) cat ON story_category.id = cat.id WHERE cat.id IS NULL

.story_category 하지 않는 것category.

삭제할 행을 식별하기 위한 원래 쿼리를 다음에 나타냅니다.

SELECT * 
FROM  story_category 
WHERE category_id NOT IN (
    SELECT DISTINCT category.id 
    FROM category INNER JOIN 
       story_category ON category_id=category.id
);

★★의 NOT IN라는 를 붙여서JOIN원래의 표는 불필요하게 복잡해 보인다.은 보다 될 수 .not exists "subquery " " "subquery" :

select sc.*
from story_category sc
where not exists (select 1 from category c where c.id = sc.category_id);

제제이 a a a a a a a a a a a a a a now now now now now로 바꿀 수 있습니다.delete스테이트먼트:

delete from story_category
where not exists (select 1 from category c where c.id = story_category.category_id);    

이 쿼리는 MySQL 버전뿐만 아니라 내가 알고 있는 대부분의 다른 데이터베이스에서도 실행됩니다.

DB Fielen 데모:

-- set-up
create table story_category(category_id int);
create table category (id int);
insert into story_category values (1), (2), (3), (4), (5);
insert into category values (4), (5), (6), (7);

-- your original query to identify offending rows
SELECT * 
FROM  story_category 
WHERE category_id NOT IN (
    SELECT DISTINCT category.id 
    FROM category INNER JOIN 
       story_category ON category_id=category.id);
| category_id || ----------: ||           1 ||           2 ||           3 |
-- a functionally-equivalent, simpler query for this
select sc.*
from story_category sc
where not exists (select 1 from category c where c.id = sc.category_id)
| category_id || ----------: ||           1 ||           2 ||           3 |
-- the delete query
delete from story_category
where not exists (select 1 from category c where c.id = story_category.category_id);

-- outcome
select * from story_category;
| category_id || ----------: ||           4 ||           5 |

언급URL : https://stackoverflow.com/questions/45494/mysql-error-1093-cant-specify-target-table-for-update-in-from-clause

반응형