การเอาชนะ MySQL Error 1093 - ไม่สามารถระบุตารางเป้าหมายสำหรับการอัปเดต

เมื่อทำงานกับ MySQL คุณอาจพบกับ Error 1093 ที่น่าหงุดหงิด: “คุณไม่สามารถระบุตารางเป้าหมายสำหรับการอัปเดตใน FROM clause” ข้อผิดพลาดนี้มักเกิดขึ้นเมื่อคุณพยายามจะทำการอัปเดตหรือลบจากตารางในขณะที่เลือกจากมันในซับควอรี่นั้น ในบล็อกโพสต์นี้เราจะแยกปัญหาออกและให้วิธีแก้ไขที่มีประสิทธิภาพเพื่อให้คำสั่งของคุณทำงานได้อย่างราบรื่นอีกครั้ง

การเข้าใจปัญหา

ในสถานการณ์ที่นำเสนอ ผู้ใช้มีตารางชื่อ story_category ที่มีข้อมูลเสียหาย พวกเขาได้ลองลบข้อมูลเหล่านี้โดยใช้ซับควอรี่ในคำสั่ง DELETE ของพวกเขา:

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 - คุณไม่สามารถระบุตารางเป้าหมาย 'story_category' สำหรับการอัปเดตใน FROM clause 

ข้อผิดพลาดนี้เกิดขึ้นเนื่องจาก MySQL ไม่อนุญาตให้คุณปรับเปลี่ยนตาราง (ในกรณีนี้คือ story_category) ในขณะที่เลือกจากตารางนั้นในเวลาเดียวกัน มาดูกันว่าเราจะเอาชนะข้อจำกัดนี้ได้อย่างไร

กลยุทธ์การแก้ปัญหา

1. การใช้ Self-Join

วิธีที่มีประสิทธิภาพในการหลีกเลี่ยงข้อผิดพลาดนี้คือการใช้ self-join วิธีนี้ช่วยให้คุณปรับโครงสร้างคำสั่งของคุณเพื่อหลีกเลี่ยงการใช้ซับควอรี่โดยตรงกับตารางเป้าหมาย นี่คือวิธีการที่ทำงาน:

DELETE a
FROM story_category AS a
INNER JOIN category AS b 
ON a.category_id = b.id
WHERE b.id IS NULL;

ในตัวอย่างนี้:

  • story_category AS a หมายถึงตารางหลักที่เราต้องการปรับเปลี่ยน (หรือลบออกจากมัน)
  • category AS b คือ ตารางที่เรากำลังเข้าร่วม
  • โดยการประกันว่าเราตรงกับ ID หมวดหมู่ที่ไม่มีอยู่จริงเท่านั้น เราจึงสามารถลบข้อมูลเสียหายออกจาก story_category ได้

2. การทำซับควอรี่อย่างลึก

หากคุณจำเป็นต้องใช้ซับควอรี่ ให้พิจารณาการทำซับควอรี่อย่างลึกภายในคำสั่งหลักเพื่อสร้างตารางชั่วคราวโดยปริยาย:

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

วิธีนี้ช่วยหลีกเลี่ยงข้อผิดพลาดโดยทำให้ MySQL ถือว่าซับควอรี่ภายในเป็นตารางชั่วคราว ซึ่งทำให้ไม่เกิดการปรับเปลี่ยนตารางเป้าหมายโดยตรง

3. การปรับตั้งค่าตัวปรับแต่งการค้นหา

เริ่มตั้งแต่ MySQL เวอร์ชัน 5.7.6 มีการเปลี่ยนแปลงที่เกิดขึ้นกับตัวปรับแต่งการค้นหาซึ่งอาจยังคงส่งผลให้เกิดข้อผิดพลาดนี้ แม้จะใช้วิธีการซับควอรี่แบบซ้อน หากคุณพบปัญหานี้ คุณอาจปรับตั้งค่าตัวปรับแต่งชั่วคราว:

SET optimizer_switch = 'derived_merge=off';

คำสั่งนี้บอก MySQL ไม่ให้รวมตารางที่ได้มาซึ่งอาจช่วยในการดำเนินการคำสั่งของคุณ อย่างไรก็ตาม สิ่งสำคัญคือต้องถือว่าวิธีนี้เป็นการแก้ปัญหาระยะสั้นหรือสำหรับงานที่ทำครั้งเดียวเท่านั้น เนื่องจากอาจส่งผลต่อประสิทธิภาพและผลลัพธ์ของคำสั่ง

บทสรุป

การพบ MySQL Error 1093 เมื่อพยายามลบหรืออัปเดตข้อมูลในตารางอาจเป็นอุปสรรคที่พบได้บ่อย แต่ยังมีวิธีการที่มีประสิทธิภาพในการแก้ไขปัญหานี้ ไม่ว่าคุณจะตัดสินใจที่จะเข้าร่วมตารางกับตัวมันเอง ทำซับควอรี่ซ้อน หรือปรับการตั้งค่าตัวปรับแต่ง สิ่งสำคัญคือเลือกวิธีที่สอดคล้องกับเป้าหมายประสิทธิภาพของฐานข้อมูลของคุณ

อย่าลังเลที่จะสำรวจวิธีการเหล่านี้และปรับใช้ให้เหมาะสมกับโครงสร้างและความต้องการเฉพาะของฐานข้อมูลของคุณ ขอให้สนุกกับการค้นหาข้อมูล!