2011-01-21 4 views
10

Tôi có những gì có vẻ là một vấn đề đơn giản, nhưng không thể tìm ra giải pháp thích hợp thông qua SQL. Tôi đang sử dụng postgresql cụ thể.Truy vấn SQL trong đó TẤT CẢ các bản ghi trong một kết hợp khớp với một điều kiện?

Lấy sau:

SELECT * FROM users INNER JOIN tags ON (tags.user_id = users.id) WHERE tags.name IN ('word1', 'word2') 

này không làm những gì tôi cần. Tôi muốn tìm người dùng có thẻ CHỈ được đưa vào danh sách. Nếu người dùng có thẻ không có trong danh sách, người dùng sẽ không được bao gồm.

thẻ 'user1': word1, word2, word3
thẻ 'user2': word1
thẻ 'User3': word1, WORD2

Given: word1 và word2. Tôi muốn chuẩn bị một truy vấn trả về 'user2' và 'user3'. 'user1' bị loại trừ vì nó có thẻ không có trong danh sách.

Hy vọng tôi đã làm rõ điều này. Cảm ơn bạn đã giúp đỡ!

+2

thể trùng lặp của [? SQL, làm thế nào để phù hợp với ALL] (http://stackoverflow.com/questions/4763143/sql-how-to-match -all) –

+0

Bạn không chỉ hỏi điều này –

+0

Nếu người dùng không có thẻ nào được trả lại thì sao? – Quassnoi

Trả lời

6

Dựa vào COUNT (*) = 2 sẽ yêu cầu không thể trùng lặp user_id và tên trong bảng thẻ. Nếu là vậy, tôi sẽ đi con đường đó. Nếu không, điều này sẽ làm việc:

SELECT u.* 
FROM users AS u 
WHERE u.id NOT IN (
    SELECT DISTINCT user_id FROM tags WHERE name NOT IN ('word1', 'word2') 
) AND EXISTS (SELECT user_id FROM tags WHERE user_id = u.id) 
+2

Điều này * có thể * bao gồm người dùng không có thẻ. –

+0

@Andriy M: Bạn đã đúng. Tôi đã cập nhật câu trả lời của mình cho tài khoản này ngay bây giờ. Cảm ơn vì chỉ ra điều ấy. – nybbler

+0

'DISTINCT' chỉ là phụ phí ở đây ... – JNK

1
SELECT user_id 
FROM users 
WHERE id IN 
     (
     SELECT user_id 
     FROM tags 
     ) 
     AND id NOT IN 
     (
     SELECT user_id 
     FROM tags 
     WHERE name NOT IN ('word1', 'word2') 
     ) 

hoặc

SELECT u.* 
FROM (
     SELECT DISTINCT user_id 
     FROM tags 
     WHERE name IN ('word1', 'word2') 
     ) t 
JOIN users u 
ON  u.id = t.user_id 
     AND t.user_id NOT IN 
     (
     SELECT user_id 
     FROM tags 
     WHERE name NOT IN ('word1', 'word2') 
     ) 
+0

Thao tác này sẽ trả về tất cả người dùng khớp với cả hai từ mà không kiểm tra xem chúng có khớp với các từ khác hay không. Điều này không trả lời câu hỏi. – GolezTrol

+0

@GolezTrol: có nhiệm vụ sai, cảm ơn vì đã chỉ. – Quassnoi

0

Để có được tất cả người dùng mà không có thẻ mà không có trong danh sách, sử dụng truy vấn dưới đây. Có thể người dùng được trả lại không có thẻ hoặc chỉ một thẻ khớp với các từ, nhưng tôi hiểu đó là chức năng mong muốn.

SELECT 
    u.* 
FROM 
    users u 
    LEFT JOIN tags t 
    ON t.user_id = u.userid AND 
     t.name NOT IN ('word1', 'word2') 
WHERE 
    t.user_id IS NULL 
0
SELECT u.* 
FROM users u 
INNER JOIN (
    SELECT user_id FROM tags WHERE name IN ('word1', 'word2') 
    EXCEPT 
    SELECT user_id FROM tags WHERE name NOT IN ('word1', 'word2') 
) s ON u.id = s.user_id 
0
SELECT distinct users.id 
FROM users 
INNER JOIN tags ON (tags.user_id = users.id) 
group by users.id 
having count(*) = 2 
and min(tags.name) = 'word1' 
and max(tags.name) = 'word2' 
+1

Bạn có thể cung cấp một số giải thích về lý do truy vấn của bạn tốt hơn những gì đã được đăng không? – Theresa