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 。category
table.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 JOIN
OP:
SELECT s.*
FROM story_category s
LEFT JOIN category c
ON c.id=s.category_id
WHERE c.id IS NULL;
★★★★★★DELETE s
는 삭제 을 「삭제」로합니다.story_category
table.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 버전뿐만 아니라 내가 알고 있는 대부분의 다른 데이터베이스에서도 실행됩니다.
-- 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
'programing' 카테고리의 다른 글
네스트된 Vuej 슬롯: 슬롯을 손자녀에게 전달하는 방법 (0) | 2022.10.04 |
---|---|
Larabel 3/4에서 쿼리 실행 (0) | 2022.10.04 |
MySQL 오더로 인해 쿼리가 느리게 해결되지만 이유는 확실하지 않습니다. (0) | 2022.10.04 |
Java 응용 프로그램을 Pacebooker를 사용하여 MariaDB 서버에 연결 (0) | 2022.10.04 |
정적 변수는 스레드 간에 공유됩니까? (0) | 2022.10.04 |