2010-07-16 11 views
18

मैं ऑब्जेक्ट्स के लिए पूछताछ करने का प्रयास कर रहा हूं जो टैग के दिए गए सेट से मेल खाते हैं।MySQL कई टैग्स (कई से कई रिश्ते) के लिए पूछताछ में शामिल है जो सभी टैग से मेल खाता है?

असल में मैं चाहता हूं कि उपयोगकर्ता अपने खोज परिणामों को फ़िल्टर करने या "संकीर्ण" करने के लिए अधिक से अधिक टैग जोड़ने में सक्षम हों, जैसे newegg.com करता है।

मेरी तालिका संरचना ऑब्जेक्ट्स की एक तालिका है, टैग की एक तालिका है, और एक बहुत: कई संबंध तालिका ऑब्जेक्ट्सगैग।

SELECT * FROM Objects 
LEFT OUTER JOIN ObjectsTags ON (Objects.id=ObjectsTags.object_id) 
LEFT OUTER JOIN Tags ON (Tags.id=ObjectsTags.tag_id) 

मैं एक में खंड/हालत का उपयोग कर, इस तरह की कोशिश की:: तो मैं बहुत की तरह एक में शामिल हों प्रश्न हैं

SELECT * FROM Objects 
LEFT OUTER JOIN ObjectsTags ON (Objects.id=ObjectsTags.object_id) 
LEFT OUTER JOIN Tags ON (Tags.id=ObjectsTags.tag_id) 
WHERE Tags.name IN ('tag1','tag2') 
GROUP BY Objects.id 

लेकिन मुझे पता चला कि यह अन्य के एक श्रृंखला है, इसलिए अधिक टैग simulates आप जितनी अधिक उम्मीद कर रहे थे, उतनी कम हो गई परिणाम सेट की बजाय आप जितनी अधिक परिणाम प्राप्त करेंगे, क्वेरी में जोड़ दें।

मैं भी कई तरह जहां की स्थिति, एक साथ anded कर की कोशिश की:

SELECT * FROM Objects 
LEFT OUTER JOIN ObjectsTags ON (Objects.id=ObjectsTags.object_id) 
LEFT OUTER JOIN Tags ON (Tags.id=ObjectsTags.tag_id) 
WHERE Tags.name LIKE 'tag1' 
AND Tags.name LIKE 'tag2' 
GROUP BY Objects.id 

लेकिन यह कोई परिणाम है, जब परिणाम एक साथ बांटा जाता है के बाद से बाहरी में शामिल हो गए Tags.name स्तंभ सिर्फ 'tag1' शामिल है, और 'टैग 2' भी नहीं। परिणाम पंक्ति जहां मिलान किया गया 'टैग 2' ग्रुपिंग द्वारा "छुपा" है।

मैं "संकीर्ण डाउन" या "ड्रिल डाउन" प्रभाव प्राप्त करने के लिए सभी टैग कैसे मिलान कर सकता हूं, जिसके बाद मैं हूं? धन्यवाद।

उत्तर

26

उपयोग:

SELECT * 
    FROM OBJECTS o 
    JOIN OBJECTSTAGS ot ON ot.object_id = o.id 
    JOIN TAGS t ON t.id = ot.tag_id 
    WHERE t.name IN ('tag1','tag2') 
GROUP BY o.id 
    HAVING COUNT(DISTINCT t.name) = 2 

आप HAVING क्लॉज़ लापता हैं।

यदि आप केवल उन पंक्तियों को चाहते हैं जहां दोनों टैग मौजूद हैं, तो बाएं जॉइन की आवश्यकता नहीं है।

+1

डायबिनेट आवश्यक है यदि आपके पास ऑब्जेक्ट्स में कॉलम की जोड़ी पर प्राथमिक कुंजी या अद्वितीय बाधा/अनुक्रमणिका नहीं है, यह सुनिश्चित करने के लिए कि डुप्लिकेट नहीं हैं (ये झूठी सकारात्मक होंगे)। –

+0

बहुत अच्छा काम करता है! धन्यवाद! पंक्ति गणना के साथ इस तरह से हैविंग का उपयोग करने का विचार कभी नहीं किया। अन्य लोगों के लिए एफवाईआई: मैं PHP में अपनी क्वेरी बना रहा हूं ताकि हैविंग क्लॉज उन टैग्स की संख्या से मेल खाए जो मैं खोज रहा हूं, इसलिए यदि यह ('टैग 1', 'टैग 2', 'टैग 3') है, तो मैं हैविंग की तलाश में हूं COUNT (DISTINCT t.name) = 3, यह सुनिश्चित करने के लिए कि उसके परिणाम में सभी टैग हैं। – thaddeusmt

+0

बहुत बढ़िया जवाब। धन्यवाद ! –

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