sql - एसक्यूएल कैसे कई रिश्ते के लिए कई खोज करने के लिए




search many-to-many (5)

आप इस बारे में कुछ नहीं कहते हैं कि यह कैसे कई-से-कई रिश्ते हैं। मुझे लगता है कि लेबल तालिका में लेबल्स (नोटिड: इंट, लेबल: वर्चार) है - प्राथमिक कुंजी के साथ दोनों में फैले?

SELECT DISTINCT n.id from notes as n, notes_labels as nl WHERE n.id = nl.noteid AND nl.text in (label1, label2);

अपने कॉलम नामों के साथ बदलें, और लेबल के लिए उचित प्लेसहोल्डर डालें

मेरे पास दो मुख्य टेबल notes और labels साथ एक डेटाबेस है उनके पास कई-से-कई रिश्ते हैं (जैसे स्टैकेवरफ्लो डॉटकॉम के लेबल के साथ प्रश्न हैं)। मैं क्या सोच रहा हूं, मैं एसक्यूएल का इस्तेमाल करते हुए कई लेबलों का उपयोग कर एक नोट कैसे खोज सकता हूं?

उदाहरण के लिए अगर मेरे पास तीन लेबल "एक", "दो" और "तीन" के साथ एक नोट "टेस्ट" है और मेरे पास एक दूसरा नोट "test2" है जिसमें लेबल "एक" और "दो" एसक्यूएल क्वेरी क्या है लेबल्स "एक" और "दो" के साथ जुड़े सभी नोट मिल जाए?


उन नोटों का विवरण प्राप्त करने के लिए जिनके लेबल 'वन' और 'दो' हैं:

select * from notes
where note_id in
( select note_id from labels where label = 'One'
  intersect
  select note_id from labels where label = 'Two'
)

नोट: मैंने वास्तव में इसका परीक्षण नहीं किया है। यह भी मान लिया गया है कि आपके पास नोट-लबेल नामक कई-से-कई टेबल हैं, जो बिल्कुल भी मामला न हो।

यदि आप बस किसी भी लेबल वाले नोट्स चाहते हैं, तो ऐसा कुछ ऐसा हो सकता है

SELECT DISTINCT n.id, n.text
FROM notes n
INNER JOIN notes_labels nl ON n.id = nl.note_id
INNER JOIN labels l ON nl.label_id = l.id
WHERE l.label IN (?, ?)

यदि आप सभी लेबल्स के नोट्स चाहते हैं, तो थोड़ा अतिरिक्त काम है

SELECT n.id, n.text
FROM notes n
INNER JOIN notes_labels nl ON n.id = nl.note_id
INNER JOIN labels l ON nl.label_id = l.id
WHERE l.label IN (?, ?)
GROUP BY n.id, n.text
HAVING COUNT(*) = 2;

? एक एसक्यूएल प्लेसहोल्डर है और 2 आपके द्वारा खोजे जाने वाले टैग की संख्या है। यह मान रहा है कि लिंक तालिका में दोनों आईडी कॉलम एक मिश्रित प्राथमिक कुंजी के रूप में है।


मान लें कि आपके पास सामान्यीकृत डाटाबेस है, notes और labels बीच आपके पास एक अन्य तालिका होना चाहिए

आपको तब तालिकाओं में शामिल inner join लिए एक inner join का उपयोग करना चाहिए

  1. बाइंड टेबल के साथ labels तालिका में शामिल हों (बहुत-से-कई टेबल)
  2. पिछली क्वेरी के साथ notes तालिका में शामिल हों

उदाहरण:

select * from ((labels l inner join labels_notes ln on l.labelid = ln.labelid) inner join notes n on ln.notesid = n.noteid)

इस तरह, आपने दोनों तालिकाओं को एक साथ जोड़ दिया है।

अब आपको जो कुछ जोड़ने की जरूरत है वह where है ... लेकिन मैं इसे आपके ऊपर छोड़ दूँगा


select * from notes a
inner join notes_labels mm on (mm.note = a.id and mm.labeltext in ('one', 'two') )

बेशक, अपने वास्तविक स्तंभ नामों के साथ बदलें, उम्मीद है कि आपकी तालिका के बारे में मेरी मान्यताओं सही थीं।

और वास्तव में आपके प्रश्न में संभवतः अस्पष्टता का थोड़ा सा अंग्रेजी के लिए धन्यवाद है और शब्द और कभी-कभी कैसे उपयोग किया जाता है। यदि आप का मतलब है कि आप देखना चाहते हैं, उदाहरण के लिए, एक नोट 'एक' पर टैग किया गया है, लेकिन 'दो' नहीं है, यह काम करना चाहिए (अपने 'और' का मतलब करने के लिए, 'मुझे लेबल के साथ सभी नोट' एक 'और / अधिक सभी को दिखाएं लेबल 'दो' के साथ नोट) हालांकि, यदि आप केवल नोट्स चाहते हैं जो दोनों लेबल हैं, तो यह इसके बारे में जाने का एक तरीका होगा:

select * from notes a
where exists (select 1 from notes_labels b where b.note = a.id and b.labeltext = 'one')
     and exists (select 1 from notes_labels c where c.note = a.id and c.labeltext = 'two')

संपादित करें: सभी सुझावों के लिए धन्यवाद, मेरे दिमाग में सोमवार गियर थोड़ी धीमी गति से दिखता है ... ऐसा लगता है कि मुझे इसे विकी होना चाहिए था!







relational-division