2009-07-20 20 views
5

Lấy ví dụ một ứng dụng có người dùng, mỗi ứng dụng có thể nằm trong một nhóm chính xác. Nếu chúng ta muốn chọn danh sách các nhóm không có thành viên, thì SQL chính xác là gì? Tôi cứ cảm thấy như sắp nắm lấy truy vấn, và rồi nó lại biến mất.Chọn tất cả các mục trong bảng không xuất hiện trong khóa ngoài của một bảng khác

Điểm thưởng - được đưa ra senario thay thế, trong đó có nhiều cặp ghép nối, SQL là gì để xác định các nhóm không sử dụng?

(nếu bạn muốn tên trường cụ thể :) One-To-Nhiều:

Table 'users': | user_id | group_id | 
Table 'groups': | group_id | 

Nhiều-To-Nhiều:

Table 'users': | user_id | 
Table 'groups': | group_id | 
Table 'user-group': | user_id | group_id | 
+0

Cảm ơn cả hai câu trả lời, cả hai đều hoạt động. Tôi tò mò nếu có bất kỳ sự khác biệt chức năng giữa hai phương pháp. – dimo414

+0

@ dimo414 - ít nhất là trong Sql Server (2005), kế hoạch thực hiện cho phiên bản của tôi ngắn hơn và có chi phí * thấp hơn * thấp hơn. Thực sự, nó sẽ được xuống mà một trong những bạn xem xét dễ đọc hơn, trừ khi bạn đang sử dụng bộ dữ liệu lớn! =) – Rob

+0

Tuy nhiên - chỉ cần chạy cả hai truy vấn trong cùng một lô với 65.536 hàng trong users_groups, truy vấn của tôi chiếm 1% chi phí lô và t'other là 99% của lô - cả hai vẫn được thực hiện trong ít hơn một thứ hai trong tổng số mặc dù – Rob

Trả lời

4

nhóm mà không có các thành viên (đối với cặp đôi nhiều-nhiều):

SELECT * 
FROM groups g 
WHERE NOT EXISTS 
    (
     SELECT 1 
     FROM users_groups ug 
     WHERE g.groupid = ug.groupid 
    ); 

Sql này cũng sẽ làm việc trong ví dụ "đầu tiên" của bạn như bạn có thể thay thế "người sử dụng" cho "users_groups" trong sub-query =)

theo như hiệu suất là có liên quan, tôi biết rằng truy vấn này có thể khá performant trên Sql server, nhưng tôi không như vậy chắc chắn như thế nào MySql thích nó ..

2

Đối với người đầu tiên, hãy thử này:

SELECT * FROM groups 
LEFT JOIN users ON (groups.group_id=users.group_id) 
WHERE users.user_id IS NULL; 

Đối với dịch vụ thứ hai, hãy thử điều này:

SELECT * FROM groups 
LEFT JOIN user-group ON (groups.group_id=user-group.group_id) 
WHERE user-group.user_id IS NULL; 
1
SELECT * 
FROM groups 
WHERE groups.id NOT IN (
    SELECT user.group_id 
    FROM user 
) 

Nó sẽ retur n tất cả id nhóm không có trong người dùng

Các vấn đề liên quan