2011-06-22 39 views
10

Tôi có một bảng có nhiều mục lịch sử chứa ID khách hàng.Cách thanh lịch để xóa các hàng mồ côi?

Có một bảng khách hàng riêng biệt. Đôi khi một số mục nhập của khách hàng bị xóa. Có một cách dễ dàng, không lặp qua từng mục nhập lịch sử, để thả tất cả các hàng trong bảng lịch sử nơi ID khách hàng không còn tồn tại do hàng của khách hàng đã bị xóa không? Không có thông tin chi tiết.

+0

Bạn có muốn xóa mỗi khi khách hàng bị xóa hoặc chỉ định kỳ? –

Trả lời

25
delete from history_table where customer_id not in (select customer_id from customers) 

đã bạn có nghĩa là một cái gì đó như thế này?

+0

Điểm yếu của nó là nó không thể xử lý self-join (ví dụ như parentid trong bảng). Nó cũng có thể chậm hơn so với tham gia thích hợp ... nhưng điều đó có thể không đáng kể trên các bảng nhỏ. –

8
DELETE h.* FROM history h 
LEFT JOIN customer c ON h.customer_id = c.id 
WHERE c.id IS NULL 

Tôi đang nhập từ đầu của tôi, nhưng bạn sẽ có được ý tưởng hy vọng.

Delete syntax documentation

+0

Đây là giải pháp thích hợp. –

5

Làm thế nào về:

DELETE FROM history_table 
WHERE customer_id NOT IN (SELECT customer_id FROM customer); 
1
DELETE FROM CUSTOMER_HISTORY CH 
WHERE NOT EXIST (SELECT 1 FROM CUSTOMER C WHERE C.CUSTOMER_ID = CH.CUSTOMER_ID) 
4

Bạn có thể sử dụng xếp tầng với khóa ngoài để thực hiện việc này. Trong ví dụ sau, bất kỳ lúc nào một hàng bị xóa khỏi A hoặc A_ID trong A được thay đổi, thay đổi này sẽ tự động được phản ánh trong bảng B. Bạn có thể đọc thêm về khóa ngoài in the MySql Documentation.

CREATE TABLE A(
    A_ID INT, 
    PRIMARY_KEY(A_ID) 
) TYPE=InnoDB; 

CREATE TABLE B(
    B_ID INT, 
    A_ID INT, 
    CONSTRAINT FK_B_A FOREIGN KEY REFERENCES A(A_ID) ON DELETE CASCADE ON UPDATE CASCADE, 
    PRIMARY_KEY(B_ID, A_ID) 
) TYPE=InnoDB; 
Các vấn đề liên quan