2011-01-21 15 views
10

मेरे पास एक साधारण समस्या है, लेकिन एसक्यूएल के माध्यम से उचित समाधान का पता नहीं लगा सकता है। मैं विशेष रूप से postgresql का उपयोग कर रहा हूँ।एसक्यूएल क्वेरी जहां एक जॉइन में सभी रिकॉर्ड एक शर्त से मेल खाते हैं?

समझें:

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

यह मैं क्या जरूरत है नहीं करता है। मैं उन उपयोगकर्ताओं को ढूंढना चाहता हूं जिनके टैग केवल सूची में शामिल हैं। यदि उपयोगकर्ता के पास एक टैग है जो सूची में नहीं है, तो उपयोगकर्ता को शामिल नहीं किया जाना चाहिए।

'user1' टैग:, word1

को देखते हुए WORD2: word1
'user3' टैग: word1, WORD2,
'user2' टैग word3 word1 और WORD2। मैं एक क्वेरी तैयार करना चाहता हूं जो 'user2' और 'user3' देता है। 'user1' को बाहर रखा गया है क्योंकि इसमें एक टैग है जो सूची में नहीं है।

उम्मीद है कि मैंने यह स्पष्ट कर दिया है। आपकी सहायताके लिए धन्यवाद!

+2

संभव डुप्लिकेट [? एसक्यूएल, कैसे मेल करने के लिए सभी] (http://stackoverflow.com/questions/4763143/sql-how-to-match -all) –

+0

क्या आपने अभी यह –

+0

नहीं पूछा था, जिन उपयोगकर्ताओं को कोई टैग नहीं है, उन्हें वापस लौटाया जाना चाहिए? – Quassnoi

उत्तर

6

COUNT पर निर्भर (*) = 2 की आवश्यकता होगी कि वहाँ user_id और टैग तालिका में नाम का कोई डुप्लिकेट हो सकता है। अगर ऐसा है, तो मैं उस मार्ग पर जाऊंगा। अन्यथा, यह काम करना चाहिए:

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

यह * * बिना टैग वाले उपयोगकर्ताओं को शामिल कर सकता है। –

+0

@ एंड्री एम: आप सही हैं। मैंने अभी इसके लिए मेरा जवाब अपडेट कर दिया है। यह इंगित करने के लिए धन्यवाद। – nybbler

+0

'DISTINCT' यहां अतिरिक्त ओवरहेड है ... – 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') 
     ) 

या

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

यह उन सभी उपयोगकर्ताओं को वापस करेगा जो दोनों शब्दों से मेल खाते हैं, बिना जांच किए कि वे अन्य शब्दों से मेल नहीं खाते हैं। यह सवाल का जवाब नहीं देता है। – GolezTrol

+0

@GolezTrol: कार्य गलत है, पॉइंटिंग के लिए धन्यवाद। – Quassnoi

0

सभी उपयोगकर्ताओं को एक टैग है कि सूची में नहीं है की जरूरत नहीं है पाने के लिए, नीचे दिए गए क्वेरी का उपयोग करें। हो सकता है कि उपयोगकर्ता लौटाए जाएं जिनके पास कोई टैग नहीं है या शब्दों से मेल खाने वाला केवल एक टैग है, लेकिन मैं समझता हूं कि वांछित कार्यक्षमता है।

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

क्या आप कुछ स्पष्टीकरण प्रदान कर सकते हैं कि आपकी क्वेरी पहले से पोस्ट की गई तुलना में बेहतर क्यों है? – Theresa

संबंधित मुद्दे