2011-12-08 24 views
24

Ok, vì vậy tôi có một bảng tạm thời chứa userID và taskID. Nó được gọi là CompletedTasks. Tôi có một bảng thứ hai có chứa userID và taskID. Nó được gọi là PlannedTasks.mysql "Không ở đâu" bằng hai cột

Tôi cần có danh sách tất cả các tác vụ đã hoàn tất nhưng không được lên kế hoạch. Vì vậy, tôi cần phải bằng cách nào đó loại bỏ từ nhiệm vụ hoàn thành tất cả các hàng nơi cả hai PlannedTasks.userID != CompletedTasks.userID AND PlannedTasks.taskID != CompletedTasks.taskID.

Tôi hy vọng câu hỏi này có ý nghĩa. Xin vui lòng cho tôi biết nếu nó không rõ ràng và tôi sẽ giải thích thêm.

Cảm ơn mọi mẹo!

+0

Tôi nghĩ bạn cần một cột bổ sung để cho biết trạng thái, không thực sự cần hai bảng. – ajreal

+0

@ajreal Đó là một điểm tốt. Có lẽ tôi sẽ xem xét tinh chỉnh lược đồ theo cách bạn đề xuất. Đánh giá cao mẹo! – PFranchise

+1

Tôi thích 2 bảng trên một bảng và một cột trạng thái, 99% thời gian. Và 11 bảng trên một bảng và 10 cột trạng thái. Không dễ để tối ưu hóa truy vấn tìm kiếm một hoặc nhiều cột trạng thái (trong MysQL). –

Trả lời

62

Bạn có thể sử dụng này (thêm cú pháp nhỏ gọn):

SELECT * 
FROM CompletedTasks 
WHERE (userID, taskID) NOT IN 
     (SELECT userID, taskID 
     FROM PlannedTasks 
    ) ; 

hoặc phiên bản NOT EXISTS (mà mặc dù phức tạp hơn, nên hiệu quả hơn với chỉ số thích hợp):

SELECT c.* 
FROM CompletedTasks AS c 
WHERE NOT EXISTS 
     (SELECT 1 
     FROM PlannedTasks AS p 
     WHERE p.userID = c.userID 
      AND p.taskID = c.taskID 
    ) ; 

và tất nhiên phiên bản LEFT JOIN/IS NULL mà @jmacinnes có trong câu trả lời của anh ấy.

+0

Tuyệt vời! Cảm ơn nhiều. Tôi không biết bạn có thể sử dụng ở đâu trên hai lĩnh vực theo cách đó, nhưng hy vọng rằng đó sẽ là một lựa chọn. cám ơn một lần nữa và chúc một ngày tốt lành. – PFranchise

+0

Làm theo các bài kiểm tra của tôi, phiên bản NOT EXISTS nhanh hơn phiên bản NOT_IN –

+0

@Ka. có, 'NOT IN' với một bộ tuple không được tối ưu hóa tốt như' NOT EXISTS'. Bạn đã thử nghiệm phiên bản nào? Tôi chưa thử nghiệm nếu họ đã cải thiện trình tối ưu hóa trong phiên bản 5.7 mới. –

5

Đây có phải là những gì bạn cần không?

select ct.* from 
completedTasks ct 
left outer join plannedTasks pt on ct.taskId = pt.TaskId and ct.userId = pt.userId 
where pt.taskId is null 

Tuy nhiên, tôi đồng ý với nhận xét - với điều kiện chúng tôi biết từ câu hỏi, cột trạng thái giống như một lược đồ tốt hơn hai bảng.

0

@ Cảm ơn ypercubeᵀᴹ để chia sẻ dưới đây truy vấn nhắc

SELECT * FROM CompletedTasks WHERE (userID, taskID) NOT IN 
     (SELECT userID, taskID FROM PlannedTasks) ;' 

Vấn đề của tôi được giải quyết.

+0

Đây phải là nhận xét, không phải là câu trả lời :) – sniperd

+0

Thực ra, tôi đã thực hiện một số thay đổi với tham chiếu đến truy vấn được chia sẻ @ypercube. Sẽ chăm sóc trong tương lai. Cảm ơn –