MySQL: समूह फ़ंक्शन का अमान्य उपयोग


105

मैं MySQL का उपयोग कर रहा हूं। यहाँ मेरा स्कीमा है:

आपूर्तिकर्ता ( साइड : पूर्णांक , sname: स्ट्रिंग, पता स्ट्रिंग)

भागों ( pid: पूर्णांक , pname: स्ट्रिंग, रंग: स्ट्रिंग)

कैटलॉग ( किनारा: पूर्णांक, पीआईडी: पूर्णांक , लागत: वास्तविक)

(प्राथमिक कुंजी बोल्ड कर रहे हैं)

मैं उन सभी भागों का चयन करने के लिए एक प्रश्न लिखने की कोशिश कर रहा हूं जो कम से कम दो आपूर्तिकर्ताओं द्वारा किए गए हैं:

-- Find the pids of parts supplied by at least two different suppliers.
SELECT c1.pid                      -- select the pid
FROM Catalog AS c1                 -- from the Catalog table
WHERE c1.pid IN (                  -- where that pid is in the set:
    SELECT c2.pid                  -- of pids
    FROM Catalog AS c2             -- from catalog
    WHERE c2.pid = c1.pid AND COUNT(c2.sid) >= 2 -- where there are at least two corresponding sids
);

सबसे पहले, मैं भी इस बारे में सही तरीका जा रहा हूँ?

दूसरे, मुझे यह त्रुटि मिलती है:

1111 - समूह फ़ंक्शन का अमान्य उपयोग

मैं क्या गलत कर रहा हूं?

जवाबों:


173

आपको उपयोग करने की आवश्यकता है HAVING, नहीं WHERE

अंतर यह है: WHEREखंड फिल्टर जो MySQL का चयन करता है। तब MySQL पंक्तियों को एक साथ समूहित करता है और आपके COUNTफ़ंक्शन के लिए संख्याओं को एकत्र करता है।

HAVINGकी तरह है WHEREकेवल ऐसा होता है, के बादCOUNT मूल्य का अभिकलन किया गया है, जैसा कि आप उम्मीद करते हैं तो यह काम करेंगे। अपनी उपश्रेणी को फिर से लिखें:

(                  -- where that pid is in the set:
SELECT c2.pid                  -- of pids
FROM Catalog AS c2             -- from catalog
WHERE c2.pid = c1.pid
HAVING COUNT(c2.sid) >= 2)

25
इसके अलावा अगर GROUP BY का उपयोग किया जाता है, तो HAVING को GROUP BY
Viacheslav

1
इसके अलावा, ग्रुप बाय की जरूरत है इससे पहले .... बैंडोलो की टिप्पणी पढ़नी चाहिए: डी
एंड्रयू

8

सबसे पहले, आप जो त्रुटि प्राप्त कर रहे हैं वह उस कारण से है जहां आप COUNTफ़ंक्शन का उपयोग कर रहे हैं - आप WHEREक्लॉज़ में एक कुल (या समूह) फ़ंक्शन का उपयोग नहीं कर सकते हैं ।

दूसरा, एक उपश्रेणी का उपयोग करने के बजाय, केवल तालिका को स्वयं में शामिल करें:

SELECT a.pid 
FROM Catalog as a LEFT JOIN Catalog as b USING( pid )
WHERE a.sid != b.sid
GROUP BY a.pid

मेरा मानना ​​है कि केवल उन पंक्तियों को वापस करना चाहिए जहां कम से कम दो पंक्तियाँ समान हैं, pidलेकिन कम से कम 2 sids हैं। यह सुनिश्चित करने के लिए कि आपने प्रति pidसमूह केवल एक पंक्ति प्राप्त की है, मैंने एक समूहन खंड लागू किया है।


क्या यह संभव है कि मुझे भी शामिल होने की आवश्यकता नहीं है? (मेरे अपडेट किए गए उत्तर को देखें, जहां मैंने एक संभावित समाधान की आपूर्ति की।)
निक हेनेर

@Rosarch, मुझे लगता है कि आप COUNT(DISTINCT sid)अपनी अपडेट की गई क्वेरी में उपयोग करना चाहते हैं ।
मार्क इलियट

sidहमेशा वैसे भी अलग नहीं होना चाहिए, क्योंकि sidऔर pidसाथ में एक प्राथमिक कुंजी बनाते हैं Catalog?
निक हेनर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.