एसक्यूएल - जहां वी.एस.


202

मेरे पास निम्नलिखित दो तालिकाएँ हैं:

1. Lecturers (LectID, Fname, Lname, degree).
2. Lecturers_Specialization (LectID, Expertise).

मैं सबसे अधिक विशेषज्ञता वाले व्याख्याता को खोजना चाहता हूं। जब मैं यह कोशिश करता हूं, तो यह काम नहीं कर रहा है:

SELECT
  L.LectID, 
  Fname, 
  Lname 
FROM Lecturers L, 
     Lecturers_Specialization S
WHERE L.LectID = S.LectID
AND COUNT(S.Expertise) >= ALL (SELECT
  COUNT(Expertise)
FROM Lecturers_Specialization
GROUP BY LectID);

लेकिन जब मैं यह कोशिश करता हूं, तो यह काम करता है:

SELECT
  L.LectID,
  Fname,
  Lname 
FROM Lecturers L,
     Lecturers_Specialization S
WHERE L.LectID = S.LectID
GROUP BY L.LectID,
         Fname,
         Lname 
HAVING COUNT(S.Expertise) >= ALL (SELECT
  COUNT(Expertise)
FROM Lecturers_Specialization
GROUP BY LectID); 

क्या कारण है? धन्यवाद।


2
क्या आप स्पष्ट कर सकते हैं कि SQL का कौन सा संस्करण आप उपयोग कर रहे हैं (MySQL, MS SQL, PostgreSQL, Oracle, आदि)। इसके अलावा, जब आप कहते हैं कि "काम नहीं कर रहा है", तो क्या आपका मतलब यह है कि परिणाम आपकी अपेक्षा के अनुरूप नहीं हैं, या यह एक संकलन / पार्स त्रुटि है?
jklemmack

2
आप MAX के बजाय सभी का उपयोग क्यों करते हैं? क्या कोई फायदा है?
स्कैन

जवाबों:


351

WHEREखंड व्यक्तिगत पंक्तियों पर एक स्थिति का परिचय देता है ; HAVINGक्लाज एकत्रीकरण पर एक शर्त पेश करता है , यानी चयन के परिणाम जहां एक ही परिणाम, जैसे कि गिनती, औसत, न्यूनतम, अधिकतम या योग, कई पंक्तियों से उत्पन्न किया गया है । आपकी क्वेरी दूसरी तरह की स्थिति (यानी एकत्रीकरण पर एक शर्त) के लिए कॉल HAVINGकरती है, इसलिए सही तरीके से काम करती है।

अंगूठे के एक नियम के रूप में, WHEREपहले GROUP BYऔर HAVINGबाद का उपयोग करें GROUP BY। यह एक बल्कि आदिम नियम है, लेकिन यह 90% से अधिक मामलों में उपयोगी है।

जब आप इस पर हों, तो आप शामिल होने के ANSI संस्करण का उपयोग करके अपनी क्वेरी को फिर से लिखना चाहें:

SELECT  L.LectID, Fname, Lname
FROM Lecturers L
JOIN Lecturers_Specialization S ON L.LectID=S.LectID
GROUP BY L.LectID, Fname, Lname
HAVING COUNT(S.Expertise)>=ALL
(SELECT COUNT(Expertise) FROM Lecturers_Specialization GROUP BY LectID)

यह खत्म WHEREहो जाएगा कि थीटा में शामिल होने की स्थिति के रूप में इस्तेमाल किया गया था ।


39

HAVINGसमुच्चय पर काम करता है। चूंकि COUNTएक समग्र कार्य है, आप इसे एक WHEREखंड में उपयोग नहीं कर सकते ।

यहाँ कुछ पूर्ण कार्य पर MSDN से पढ़ना है।


30

पहले हमें Clauses अर्थात FROM> WHERE> GROUP BY> HAVING> DISTINCT> SELECT> ORDER BY के निष्पादन का क्रम जानना चाहिए के बाद से जहां खण्ड से पहले मार डाला जाता ग्रुप द्वारा खण्ड रिकॉर्ड लगाने से फिल्टर नहीं किया जा सकता है , जहां के लिए एक ग्रुप द्वारा लागू किया रिकॉर्ड।

"HAVING WHERE के क्लॉज के समान है लेकिन समूहीकृत रिकॉर्ड्स पर लागू होता है"।

पहले WHERE क्लॉज इस स्थिति के आधार पर रिकॉर्ड प्राप्त करता है, फिर ग्रुप BY क्लॉज उन्हें तदनुसार समूहित करता है और फिर HAVING क्लॉज समूह के रिकॉर्ड को स्थिति के आधार पर प्राप्त करता है।


क्या संचालन का यह क्रम हमेशा उपयोग किया जाता है? यदि क्वेरी ऑप्टिमाइज़र आदेश को बदल देता है तो क्या होगा?
MSIS

1
@MSIS भले ही क्वेरी ऑप्टिमाइज़र आदेश को बदल देता है, परिणाम उसी तरह होना चाहिए जैसे कि इस आदेश का पालन किया गया था। यह एक तार्किक आदेश है।
स्टीफन

18
  1. जहां क्लॉज का चयन SELECT, INSERT और UPDATE स्टेटमेंट्स के साथ किया जा सकता है, वहीं HAVING को सेलेक्ट स्टेटमेंट के साथ ही इस्तेमाल किया जा सकता है।

  2. एकत्रीकरण (ग्रुप बाय) से पहले पंक्तियों को कहाँ फ़िल्टर किया जाता है, जबकि एकत्रीकरण के बाद फ़िल्टरिंग समूहों को किया जाता है।

  3. जब तक यह HAVING क्लॉज में समाहित नहीं है तब तक एग्रिगेट फ़ंक्शन का उपयोग WHERE क्लॉज में नहीं किया जा सकता है, जबकि एग्रीगेट फ़ंक्शन का उपयोग HAVING क्लॉज में किया जा सकता है।

स्रोत


11

एक प्रश्न में दोनों का उदाहरण नहीं देखा। तो यह उदाहरण मदद कर सकता है।

  /**
INTERNATIONAL_ORDERS - table of orders by company by location by day
companyId, country, city, total, date
**/

SELECT country, city, sum(total) totalCityOrders 
FROM INTERNATIONAL_ORDERS with (nolock)
WHERE companyId = 884501253109
GROUP BY country, city
HAVING country = 'MX'
ORDER BY sum(total) DESC

यह कंपनी द्वारा पहले तालिका को फ़िल्टर करता है, फिर इसे (देश और शहर द्वारा) समूह करता है और इसके अलावा इसे केवल मेक्सिको के शहर एकत्रीकरण तक फ़िल्टर करता है। एकत्रीकरण में companyId की आवश्यकता नहीं थी, लेकिन हम ग्रुप BY का उपयोग करने से पहले सिर्फ पंक्तियों को फ़िल्टर करने के लिए WHERE का उपयोग करने में सक्षम थे।


जैसा कि आप परिवर्तित कर सकते हैं यह एक अच्छा उदाहरण नहीं है: `WHERE companyId = 884501253109 ग्रुप देश से, शहर HAVING देश = 'MX'` को: `WHERE companyId = 884501253109, देश = 'MX MX ग्रुप' शहर
से`

अगर आपने [देश] को फ़िल्टर करने का सुझाव दिया है, जहां पर आपने सुझाव दिया है, तो चयन [देश] से त्रुटि होगी, क्योंकि [देश] अब समूह द्वारा एकत्रीकरण में शामिल नहीं है, इसलिए इसे चुना नहीं जा सकता है।
Nhan

ऑप्टिमाइज़ेशन पर आपकी बात [देश] को व्हाट्सएप पर ले जाया जाता है क्योंकि बाद में ग्रुप बीवाई के साथ एक छोटा डेटा सेट होगा। बेशक यह संभव उपयोगों को चित्रित करने के लिए सिर्फ एक उदाहरण है। हम HAVING राशि (कुल)> 1000 में बदल सकते हैं और जो WHERE और HAVING को शामिल करने के लिए पूरी तरह से मान्य मामला होगा।
Nhan

9

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

उदाहरण क्वेरी:

select empName, sum(Bonus) 
from employees 
order by empName 
having sum(Bonus) > 5000;

यह रिजल्ट को एक अस्थायी मेमोरी में स्टोर करेगा, फिर क्लॉज होने से अपना काम करेगा। तो हम आसानी से यहाँ कुल कार्यों का उपयोग कर सकते हैं।


2
मुझे लगता है कि हम ग्रुप द्वारा क्लाज के बिना HAVING क्लॉज का उपयोग नहीं कर सकते। HAVING क्लॉज की स्थिति - Select -> FROM -> WHERE -> GROUP BY -> HAVING -> ORDER BY
Morez

4

1. हम HAVING क्लॉज के साथ कुल फ़ंक्शन का उपयोग कर सकते हैं न कि WHERE क्लॉज जैसे मिन, मैक्स, एवीजी।

2. क्‍लॉज ने टपल को रिकॉर्ड टपल को हटा दिया HAVING क्‍लॉज ने समूचे समूह को समूह के संग्रह से हटा दिया

अधिकतर HAVING का उपयोग तब किया जाता है जब आपके पास डेटा का समूह होता है और जब आप पंक्तियों में डेटा होते हैं तो WHERE का उपयोग किया जाता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.