Làm thế nào để xóa từ nhiều bảng trong MySQL?


116

Tôi đang cố gắng xóa từ một vài bảng cùng một lúc. Tôi đã thực hiện một chút nghiên cứu và đã đưa ra

DELETE FROM `pets` p,
            `pets_activities` pa
      WHERE p.`order` > :order
        AND p.`pet_id` = :pet_id
        AND pa.`id` = p.`pet_id`

Tuy nhiên, tôi nhận được lỗi này

Uncaught Database_Exception [1064]: Bạn có lỗi trong cú pháp SQL của mình; kiểm tra hướng dẫn tương ứng với phiên bản máy chủ MySQL của bạn để biết đúng cú pháp để sử dụng gần 'p, pets_activitiespa ...

Tôi chưa bao giờ thực hiện xóa bảng chéo trước đây, vì vậy bây giờ tôi thiếu kinh nghiệm và bị mắc kẹt!

Tôi đang làm gì sai?

Câu trả lời:


204

Sử dụng một JOINtrong DELETEtuyên bố.

DELETE p, pa
      FROM pets p
      JOIN pets_activities pa ON pa.id = p.pet_id
     WHERE p.order > :order
       AND p.pet_id = :pet_id

Ngoài ra, bạn có thể sử dụng ...

DELETE pa
      FROM pets_activities pa
      JOIN pets p ON pa.id = p.pet_id
 WHERE p.order > :order
   AND p.pet_id = :pet_id

... chỉ xóa từ pets_activities

Xem này .

Đối với xóa bảng duy nhất, nhưng với toàn vẹn tham chiếu, có những cách khác làm với EXISTS, NOT EXISTS, IN, NOT INvà vv Nhưng một trong những trên, nơi bạn chỉ định mà từ đó bảng để xóa với một bí danh trước khi FROMkhoản có thể giúp bạn có được ra khỏi một vài chặt chẽ khá đốm dễ dàng hơn. Tôi có xu hướng tiếp cận tới EXISTS99% các trường hợp và sau đó có 1% trong đó cú pháp MySQL này diễn ra trong ngày.


7
Tôi đã thử "xóa tất cả trong 1 truy vấn" này bằng cách nối 6 bảng lớn (mọi người khoảng ~ 15k hàng) và truy vấn mất 155 giây để xóa 63 hàng trong 6 bảng: O
Klemen Tušar

1
@cadman Đây là câu trả lời đúng; có thể có tranh luận về việc sử dụng nó, nhưng đôi khi nó rất hữu ích
Simon Christian

1
+1 Tôi đồng ý rằng điều này trong câu trả lời đúng, vì câu hỏi không phải là "bạn nên" mà là "làm thế nào". Tuy nhiên, tôi sẽ thích nghe về 1% vì tôi không thể nghĩ đến một tình huống duy nhất trong đó điều này sẽ được ưu tiên.
Erick Robertson

2
@Techouse, bạn đã tham gia và lọc trên các chỉ số? 15k x 15k x 15k x 15k 15k x 15k là 11 triệu đồng. Có SELECTmất một thời gian tương tự?
Paul Draper

6
Bạn cũng có thể sử dụng LEFT THAM GIA, rất hữu ích nếu bảng thứ hai không có mục phù hợp, nếu không sẽ không có gì bị xóa.
Lexib0y

20

Vì đây có vẻ là mối quan hệ cha / con đơn giản giữa petspets_activities, bạn nên tạo ra ràng buộc khóa ngoại của mình bằng cách xóa tầng.

Theo cách đó, khi một petshàng bị xóa, các pets_activitieshàng liên quan đến nó cũng sẽ tự động bị xóa.

Sau đó, truy vấn của bạn trở nên đơn giản:

delete from `pets`
    where `order` > :order
      and `pet_id` = :pet_id

3
@Erick, miễn là bạn đã thiết lập tính toàn vẹn tham chiếu, việc xóa tầng có thể không gây ra nhiều rắc rối hơn là tự mình xóa. Chúng tôi đã biết rằng đó palà một đứa trẻ thích hợp pdo id/pet_idánh xạ.
paxdiablo

14
Chà, các bạn có suy nghĩ của riêng mình nhưng có vẻ như bạn đang giảm giá rất nhiều sức mạnh của DBMS '. Xóa phân tầng cũng là một phần của quản lý dữ liệu như trình kích hoạt, quy trình được lưu trữ hoặc các ràng buộc và chúng chỉ nguy hiểm nếu bạn không biết bạn đang làm gì. Tuy nhiên, tôi sẽ không tranh luận thêm về vấn đề này, chúng ta sẽ phải đồng ý không đồng ý.
paxdiablo

8
Erick, bây giờ bạn đã khơi gợi sự quan tâm của tôi. Làm thế nào để bạn đảm bảo tính toàn vẹn dữ liệu trong cơ sở dữ liệu mà không bị ràng buộc?
paxdiablo

4
@Erick nói, "Tôi cũng không sử dụng kích hoạt, thủ tục được lưu trữ hoặc các ràng buộc." À, bạn dùng Excel. :-)
james.garriss

4
Tôi chỉ muốn theo dõi về điều này. Tôi đã thay đổi vị trí của mình trong việc xóa các tầng trong tình huống này. Tôi đã là một phần của môi trường SQL mới sử dụng chúng và sử dụng chúng rất tốt và chúng rất có tổ chức. Trong hệ thống này, nó hoạt động rất tốt với lợi thế của chúng tôi để có các tầng này tại chỗ. Nó chắc chắn ngăn chặn dữ liệu mồ côi và không nguy hiểm. Vấn đề là mọi người làm việc với cơ sở dữ liệu cần phải hiểu cách sử dụng chúng một cách an toàn. Nhưng luôn có những rủi ro khi các nhà phát triển cơ sở đang thực hiện các thay đổi cơ sở dữ liệu không được giám sát.
Erick Robertson

14

Dùng cái này

DELETE FROM `articles`, `comments` 
USING `articles`,`comments` 
WHERE `comments`.`article_id` = `articles`.`id` AND `articles`.`id` = 4

hoặc là

DELETE `articles`, `comments` 
FROM `articles`, `comments` 
WHERE `comments`.`article_id` = `articles`.`id` AND `articles`.`id` = 4

1
Tìm thấy một tài liệu tham khảo tốt để sử dụng điều này và một vài tùy chọn khác tại mysqltutorial.org/mysql-delete-statement.aspx
Mavelo

3

Hiện tại tôi không có cơ sở dữ liệu mysql để kiểm tra, nhưng bạn đã thử chỉ định những gì cần xóa trước mệnh đề from chưa? Ví dụ:

DELETE p, pa FROM `pets` p,
        `pets_activities` pa
  WHERE p.`order` > :order
    AND p.`pet_id` = :pet_id
    AND pa.`id` = p.`pet_id`

Tôi nghĩ rằng cú pháp bạn sử dụng được giới hạn trong các phiên bản mới hơn của mysql.


1
Truy vấn đó được thực hiện thành công, tuy nhiên, nó không xóa bất kỳ hàng nào (nhưng tôi tin rằng nó nên có).
alex

2

Cú pháp có vẻ đúng với tôi ... hãy thử thay đổi nó để sử dụng INNER JOIN...

Có một cái nhìn về điều này .


7
Quá tệ, bạn đã không bao gồm giải pháp thực tế, vì liên kết là chính xác!
mycroes

1

Đối với bất cứ ai đọc điều này vào năm 2017, đây là cách tôi đã làm một cái gì đó tương tự.

DELETE pets, pets_activities FROM pets inner join pets_activities
on pets_activities.id = pets.id WHERE pets.`order` > :order AND 
pets.`pet_id` = :pet_id

Nói chung, để xóa các hàng khỏi nhiều bảng, cú pháp tôi theo được đưa ra dưới đây. Giải pháp dựa trên giả định rằng có một số mối quan hệ giữa hai bảng.

DELETE table1, table2 FROM table1 inner join table2 on table2.id = table1.id
WHERE [conditions]

1

Tôi đã tìm thấy bài viết này chỉ cho bạn cách xóa dữ liệu khỏi nhiều bảng bằng cách sử dụng câu lệnh MySQL DELETE THAM GIA với lời giải thích tốt.

nhập mô tả hình ảnh ở đây

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.