Mysql
 sql >> डेटाबेस >  >> RDS >> Mysql

एक संबंधपरक डेटाबेस में एक सेट के लिए क्वेरी

मैं इस पर टिप्पणी नहीं करूंगा कि ऐसा करने के लिए एक बेहतर उपयुक्त स्कीमा है (यह काफी संभव है), लेकिन एक स्कीमा के लिए कॉलम name और item , निम्न क्वेरी काम करना चाहिए। (mysql सिंटैक्स)

SELECT k.name
FROM (SELECT DISTINCT name FROM sets) AS k
INNER JOIN sets i1 ON (k.name = i1.name AND i1.item = 1)
INNER JOIN sets i2 ON (k.name = i2.name AND i2.item = 3)
INNER JOIN sets i3 ON (k.name = i3.name AND i3.item = 5)
LEFT JOIN sets ix ON (k.name = ix.name AND ix.item NOT IN (1, 3, 5))
WHERE ix.name IS NULL;

विचार यह है कि हमारे पास k . में सभी सेट कुंजियां हैं , जिसे हम तब सेट आइटम डेटा के साथ sets . में जोड़ते हैं सेट में प्रत्येक सेट आइटम के लिए एक बार हम खोज रहे हैं, इस मामले में तीन। तीन आंतरिक में से प्रत्येक तालिका उपनामों के साथ जुड़ता है i1 , i2 और i3 उन सभी सेट नामों को फ़िल्टर करें जिनमें शामिल होने के साथ खोजा गया आइटम शामिल नहीं है। अंत में, हमारे पास sets . के साथ एक लेफ्ट जॉइन है तालिका उपनाम के साथ ix , जो सेट में सभी अतिरिक्त आइटम लाता है, यानी हर वह आइटम जिसे हम खोज नहीं रहे थे। ix.name NULL है इस मामले में कि कोई अतिरिक्त आइटम नहीं मिलता है, जो वास्तव में हम चाहते हैं, इस प्रकार WHERE खंड। यदि सेट पाया जाता है तो क्वेरी सेट कुंजी वाली एक पंक्ति लौटाती है, अन्यथा कोई पंक्तियाँ नहीं।

संपादित करें: Collapsars उत्तर के पीछे का विचार मेरी तुलना में बहुत बेहतर प्रतीत होता है, इसलिए यहाँ इसका थोड़ा छोटा संस्करण स्पष्टीकरण के साथ दिया गया है।

SELECT sets.name
FROM sets
LEFT JOIN (
    SELECT DISTINCT name
    FROM sets
    WHERE item NOT IN (1, 3, 5)
) s1
ON (sets.name = s1.name)
WHERE s1.name IS NULL
GROUP BY sets.name
HAVING COUNT(sets.item) = 3;

यहाँ विचार यह है कि सबक्वेरी s1 उन सभी सेटों की कुंजियों का चयन करता है जिनमें अन्य आइटम होते हैं जिन्हें हम ढूंढ रहे हैं। इस प्रकार, जब हमने छोड़ा sets . में शामिल हों s1 . के साथ , s1.name NULL है जब सेट में केवल वे आइटम होते हैं जिन्हें हम खोज रहे हैं। फिर हम सेट कुंजी के आधार पर समूह बनाते हैं और आइटमों की गलत संख्या वाले किसी भी सेट को फ़िल्टर करते हैं। फिर हमारे पास केवल ऐसे सेट रह जाते हैं जिनमें केवल वे आइटम होते हैं जिन्हें हम खोज रहे होते हैं और सही लंबाई के होते हैं। चूंकि सेट में केवल एक बार आइटम हो सकता है, उस मानदंड को पूरा करने वाला केवल एक सेट हो सकता है, और वह वह है जिसे हम ढूंढ रहे हैं।

संपादित करें: यह मुझे अभी पता चला है कि बिना बहिष्करण के इसे कैसे किया जाए।

SELECT totals.name
FROM (
    SELECT name, COUNT(*) count
    FROM sets
    GROUP BY name
) totals
INNER JOIN (
    SELECT name, COUNT(*) count
    FROM sets
    WHERE item IN (1, 3, 5)
    GROUP BY name
) matches
ON (totals.name = matches.name)
WHERE totals.count = 3 AND matches.count = 3;

पहला सबक्वेरी प्रत्येक सेट में आइटम्स की कुल संख्या का पता लगाता है और दूसरा प्रत्येक सेट में मेल खाने वाले आइटम्स की संख्या का पता लगाता है। जब matches.count 3 है, सेट में वे सभी आइटम हैं जिनकी हम तलाश कर रहे हैं, और यदि totals.count 3 भी है, सेट में कोई अतिरिक्त आइटम नहीं है।



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. ज़ेंड फ्रेमवर्क जहां क्वेरी में बयान

  2. यदि वे लारवेल प्रवास में मौजूद हैं तो अनुक्रमणिका की जाँच कैसे की जा सकती है?

  3. कोडनिर्देशक में फ़ोरैच जेनरेट की गई तालिका से कुल भुगतान की गणना करें

  4. Mysql संग्रहीत कार्यविधि निष्पादित होने पर अज्ञात स्तंभ त्रुटि देता है

  5. Yii2 . में रिलेशनल डेटा कैसे दिखाएं