HAVING और WHERE में क्या अंतर है?


260

मुझे गलत तरीके से गुगली करनी चाहिए या मैं समय से बेवकूफ बना रहा हूं।

एक बयान में HAVINGऔर क्या अंतर है ?WHERESQL SELECT

संपादित करें: मैंने स्टीवन के उत्तर को सही के रूप में चिह्नित किया है क्योंकि इसमें लिंक पर महत्वपूर्ण जानकारी शामिल थी:

जब GROUP BYउपयोग नहीं किया जाता है, तो HAVINGएक WHEREखंड की तरह व्यवहार करता है

जिस स्थिति में मैंने देखा था WHERE, वह नहीं थी GROUP BYऔर वह जगह है जहां से मेरा भ्रम शुरू हुआ। बेशक, जब तक आप यह जानते हैं कि आप इसे प्रश्न में निर्दिष्ट नहीं कर सकते।


43
आपके द्वारा बोली जाने वाली पंक्ति बिल्कुल भी महत्वपूर्ण नहीं है। Wcm के रूप में बताया गया कि बिट, HAVINGएक पोस्ट-एकत्रीकरण फ़िल्टर है, जबकि WHEREएक पूर्व-एकत्रीकरण फ़िल्टर है।
निक चम्मास

इस लिंक ने मुझे नीचे दिए गए सभी टिप्पणियों से बेहतर समझने में मदद की, सोचा कि कोई इस codeproject.com/Articles/25258/…
Lijin Durairaj

जवाबों:


93

HAVING एक समूह या एक संपूर्ण फ़ंक्शन के लिए खोज स्थिति निर्दिष्ट करता है जिसका उपयोग SELECT स्टेटमेंट में किया जाता है।

स्रोत


368

HAVING: एकत्रीकरण होने के बाद स्थितियों की जांच करने के लिए उपयोग किया जाता है।
जहां: एकत्रीकरण होने से पहले स्थितियों की जांच करने के लिए उपयोग किया जाता है।

यह कोड:

select City, CNT=Count(1)
From Address
Where State = 'MA'
Group By City

आपको एमए के सभी शहरों की तालिका और प्रत्येक शहर के पते की संख्या देता है।

यह कोड:

select City, CNT=Count(1)
From Address
Where State = 'MA'
Group By City
Having Count(1)>5

आपको 5 से अधिक पतों और प्रत्येक शहर में पतों की संख्या के साथ एमए में शहरों की एक तालिका देता है।


7
यह स्वीकृत उत्तर होना चाहिए। "होने" और "कहाँ" के बीच का अंतर यह तुरंत स्पष्ट कर देता है।
पॉल

27

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

अब WHEREभाषा से हटाने के लिए एक क्षण पर विचार करें । इस बार अस्तित्व में मौजूद अधिकांश प्रश्नों को एक स्पष्ट वैकल्पिक निर्माण के बिना फिर से लिखना होगा। कोडर्स को क्रिएटिव प्राप्त करना होगा जैसे कि एक तालिका में शामिल होने के लिए आंतरिक रूप से जाना जाता है, जिसमें पूर्व पंक्ति (जैसे DUALओरेकल) ONमें पूर्व WHEREखंड को अनुकरण करने के लिए क्लॉज का उपयोग किया जाता है । इस तरह के निर्माणों से वंचित किया जाएगा; यह स्पष्ट होगा कि भाषा से कुछ गायब था और परिणामस्वरूप स्थिति बदतर होगी।

टीएल; डीआर हम HAVINGकल खो सकते हैं और चीजें बदतर नहीं होंगी, संभवतः बेहतर होंगी, लेकिन उसी के बारे में नहीं कहा जा सकता है WHERE


यहाँ के जवाबों से, ऐसा लगता है कि बहुत से लोगों को यह पता ही नहीं है कि एक HAVINGखंड का उपयोग एक GROUP BYखंड के बिना किया जा सकता है । इस स्थिति में, HAVINGखंड को संपूर्ण तालिका अभिव्यक्ति पर लागू किया जाता है और इसके लिए आवश्यक है कि SELECTखंड में केवल स्थिरांक दिखाई दें । आमतौर पर इस HAVINGखंड में समुच्चय शामिल होंगे।

यह जितना लगता है उससे अधिक उपयोगी है। उदाहरण के लिए, इस क्वेरी पर विचार करें कि क्या यह परीक्षण nameसभी मानों के लिए अद्वितीय है T:

SELECT 1 AS result
  FROM T
HAVING COUNT( DISTINCT name ) = COUNT( name );

केवल दो संभावित परिणाम हैं: यदि HAVINGखंड सत्य है तो परिणाम एकल पंक्ति वाला होना चाहिए जिसमें मान हो1 , अन्यथा परिणाम खाली सेट होगा।


क्या यह "COUNT (DISTINCT नाम) = COUNT (नाम) FROM T" के बराबर होगा?
MSpreij

@MSpreij पता है कि अगर यह आपके लिए काम करता है, लेकिन यह SQL सर्वर 2005 पर काम नहीं करता है, लेकिन पहला काम करता है
जो

22

HAVING क्लॉज को SQL में जोड़ा गया क्योंकि WHERE कीवर्ड का उपयोग कुल कार्यों के साथ नहीं किया जा सकता है।

अधिक जानकारी के लिए इस w3schools लिंक को देखें

वाक्य - विन्यास:

SELECT column_name, aggregate_function(column_name)
FROM table_name
WHERE column_name operator value
GROUP BY column_name
HAVING aggregate_function(column_name) operator value

इस तरह एक क्वेरी:

SELECT column_name, COUNT( column_name ) AS column_name_tally
  FROM table_name
 WHERE column_name < 3
 GROUP 
    BY column_name
HAVING COUNT( column_name ) >= 3;

... एक व्युत्पन्न तालिका का उपयोग करके फिर से लिखा जा सकता है (और HAVING) को इस तरह से छोड़ देना :

SELECT column_name, column_name_tally
  FROM (
        SELECT column_name, COUNT(column_name) AS column_name_tally
          FROM table_name
         WHERE column_name < 3
         GROUP 
            BY column_name
       ) pointless_range_variable_required_here
 WHERE column_name_tally >= 3;

3
आपने बिंदु को थोड़ा याद किया: HAVINGजोड़ा गया क्योंकि व्युत्पन्न तालिकाओं को भाषा में जोड़ा नहीं गया था और जब तक कि वे एसक्यूएल तर्कसंगत रूप से पूर्ण नहीं थे और एक बार वे अनिवार्य रूप से HAVINGनिरर्थक हो गए थे ।
onedaywhen

21

ग्रुप बाय क्लॉज के संबंध में दोनों के बीच का अंतर है:

  • ग्रुप बाय के पहले कहां आता है; समूह रिकॉर्ड करने से पहले SQL WHERE क्लॉज का मूल्यांकन करता है।

  • ग्रुप बीवाई के बाद आते हैं; समूह के रिकॉर्ड के बाद SQL HAVING का मूल्यांकन करता है।

स्टेटमेंट आरेख का चयन करें

संदर्भ


चूँकि GROUP BY और HAVING दोनों वैकल्पिक हैं, आरेख दोनों मामलों को दिखाता है, बस तीर का पालन करें।
पॉल स्वेट्टे

इस प्रश्न के मेरे उत्तर से उदाहरण क्वेरी: SELECT 1 AS result FROM T HAVING...- आपके आरेख में मैं HAVINGबिना पास से नहीं जा सकता, GROUP BYलेकिन मेरी पूरी तरह से मान्य और उपयोगी क्वेरी में कोई भी नहीं है GROUP BY। मामूली बिंदु: आपके पास SELECTखंड में शाब्दिक मूल्यों को शामिल करने का विकल्प नहीं है ।
onedaywhen

@onedaywhen जब से आप अंतर्निहित ग्रुप BY के बारे में जानते हैं, आपने इसका उल्लेख क्यों नहीं किया? क्या आप जानते हैं कि यह व्यवहार वह है जो आप उम्मीद कर रहे हैं या नहीं?
पॉल स्वेट ऑक्ट

मिथिंक्स आप मुझे संदर्भ से बाहर उद्धृत कर रहे हैं। यह सवाल मानक से mySQL के स्पष्ट विचलन के बारे में था, लेकिन मेरे उत्तर के अंतिम पैराग्राफ में मानक व्यवहार का वर्णन किया गया है, और अंतिम उत्तर " अन्य उत्तरों में उल्लिखित समूह द्वारा निहित समूह" के लिए है । क्या आप कह रहे हैं कि आपके आरेख का उद्देश्य (सभी) निहित व्यवहार का वर्णन करना है? क्या वांछित व्यवहार प्राप्त करने के लिए आपको केवल उस कोड से चिपकना उपयोगी नहीं होगा जो आपको लिखने के लिए चाहिए?
onedaywhen

... मुझे नहीं पता कि दूसरे लिंक में आप किस व्यवहार को प्रस्तुत कर रहे हैं। वांछित परिणाम यह है कि आप मेरे द्वारा बताए गए वैध (स्पष्ट) पथ को दिखाने के लिए आरेख को ठीक करते हैं। इसके बारे में सोचें: आरेख पूरी क्वेरी को कवर करता है फिर भी प्रश्न केवल WHERE->HAVINGभाग में रुचि रखता है , इसलिए मुझे लगता है कि विस्तार पर ध्यान देना चाहिए। अगर आपको लगता है कि मेरा उत्तर गलत है, तो इसे संपादित करें या टिप्पणियों में सुझाए गए सुधार पोस्ट करें।
onedaywhen

12

HAVINGका उपयोग तब किया जाता है जब आप किसी समुच्चय का उपयोग कर रहे हों जैसे GROUP BY

SELECT edc_country, COUNT(*)
FROM Ed_Centers
GROUP BY edc_country
HAVING COUNT(*) > 1
ORDER BY edc_country;

8

जहां SQL द्वारा लौटाए गए सेट पर एक सीमा के रूप में लागू किया जाता है; यह SQL के बिल्ट-इन सेट ऑप्रेशन और इंडेक्स का उपयोग करता है और इसलिए परिणाम सेट को फ़िल्टर करने का सबसे तेज़ तरीका है। जब भी संभव हो हमेशा WHERE का उपयोग करें।

कुछ समग्र फ़िल्टर के लिए HAVING आवश्यक है। यह फ़िल्टर को फ़िल्टर करता है AFTER sql ने परिणामों को पुनः प्राप्त, इकट्ठा और सॉर्ट किया है। इसलिए, यह WHERE की तुलना में बहुत धीमा है और इसे उन परिस्थितियों को छोड़कर बचा जाना चाहिए जिनकी आवश्यकता है।

SQL सर्वर आपको HAVING का उपयोग करने से दूर कर देगा, तब भी जब बहुत तेज होगा। यह मत करो।


एसक्यूएल भाषा में व्युत्पन्न तालिकाओं के लिए समर्थन का अर्थ है कि आपके "कुछ छन्दों के लिए HAVING आवश्यक है" गलत है।
onedaywhen

1
ये एक अच्छा बिंदु है। तीन साल में जब से मैंने यह उत्तर लिखा है, मैं निश्चित रूप से व्युत्पन्न तालिकाओं का उपयोग करने की ओर पलायन कर रहा हूं जहां मैंने पूर्व में HAVING का उपयोग किया था। मैं इस सवाल के माध्यम से नहीं सोचा है कि क्या अभी भी कुछ उपयोग के मामले हैं जो समझ में आते हैं। मुझे यह भी पता नहीं है कि व्युत्पन्न तालिका सार्वभौमिक रूप से HAVING से बेहतर प्रदर्शन करेगी या नहीं।
davidcl

7

जहां क्लॉज कुल कार्यों के लिए काम नहीं करता है,
इसका मतलब है: आपको इस बोनस की तरह उपयोग नहीं करना चाहिए: तालिका का नाम

SELECT name  
FROM bonus  
GROUP BY name  
WHERE sum(salary) > 200  

यहाँ के बजाय जहाँ आप का उपयोग करने के लिए HAVING का उपयोग करना है ..

ग्रुप बाय क्लॉज का उपयोग किए बिना, HAVING क्लॉज सिर्फ WHERE क्लॉज के रूप में काम करता है

SELECT name  
FROM bonus  
GROUP BY name  
HAVING sum(salary) > 200  

3

अंतर b / w WHEREऔर HAVINGखंड:

WHEREऔर HAVINGक्लॉज के बीच मुख्य अंतर WHEREपंक्ति संचालन के HAVINGलिए उपयोग किया जाता है और स्तंभ संचालन के लिए उपयोग किया जाता है।

हमें HAVINGक्लॉज की आवश्यकता क्यों है ?

जैसा कि हम जानते हैं, कुल कार्य केवल स्तंभों पर किए जा सकते हैं, इसलिए हम समुच्चय में कुल कार्यों का उपयोग नहीं कर सकते हैं WHERE। इसलिए, हम HAVINGक्लॉज में कुल कार्यों का उपयोग करते हैं ।


1

एक एग्रिगेट क्वेरी में, (कोई भी क्वेरी जहां एक एग्रीगेट फ़ंक्शन का उपयोग किया जाता है) एग्रीगेटेड इंटरमीडिएट रिजल्ट सेट जनरेट होने से पहले क्लॉज का मूल्यांकन किया जाता है।

होने वाले क्लॉज में विधेयकों को कुल परिणाम पर लागू किया जाता है, इसे उत्पन्न होने के बाद। इसीलिए कुल मूल्यों पर विधेय शर्तों को क्लॉज होने में रखा जाना चाहिए, न कि कहां-कहां क्लॉज में, और क्यों आप एलॉज होने वाले क्लाज में परिभाषित उपनामों का उपयोग कर सकते हैं, लेकिन एक क्लॉज में नहीं।


1

मैं एक समस्या थी और में एक और अंतर पता चला WHEREऔर HAVING। यह अनुक्रमित स्तंभों पर उसी तरह कार्य नहीं करता है।

WHERE my_indexed_row = 123 पंक्तियों को दिखाएगा और स्वचालित रूप से अन्य अनुक्रमित पंक्तियों पर "ORDER ASC" का प्रदर्शन करेगा।

HAVING my_indexed_row = 123 सबसे पुरानी "सम्मिलित" पंक्ति से नवीनतम एक को सब कुछ दिखाता है, कोई आदेश नहीं।


आप कैसे जानते हैं कि यह आपके द्वारा उपयोग किए जा रहे विशेष SQL सर्वर के कार्यान्वयन की दुर्घटना के बजाय, जुड़वां के बीच एक परिभाषित अंतर है?
JdeBP

मैंने इसे मारियाडीबी पर परीक्षण किया। मुझे लगता है कि यह SQL सर्वर था जो मैं 8 साल पहले उपयोग कर रहा था जो विभिन्न परिणाम उत्पन्न करता था।
सिम्मोनिज़

1

जब GROUP BYउपयोग नहीं किया जाता है, WHEREऔर HAVINGखंड अनिवार्य रूप से समतुल्य होते हैं।

हालांकि, जब GROUP BYप्रयोग किया जाता है:

  • WHEREखंड एक परिणाम से फिल्टर रिकॉर्ड किया जाता है। फ़िल्टरिंग किसी भी समूह बनाने से पहले होती है।
  • HAVINGखंड (के बाद समूहों में एकत्रीकरण निष्पादित किया गया है की स्थिति की जांच करने के यानी,) एक समूह से फिल्टर मूल्यों के लिए प्रयोग किया जाता है।

यहाँ से संसाधन


होने और कहाँ अनिवार्य रूप से समकक्ष नहीं हैं। यह निष्पादन के दौरान त्रुटि देगा। HAVING क्लॉज में अमान्य है क्योंकि यह एक समुच्चय फ़ंक्शन या ग्रुप बाय क्लॉज़ में निहित नहीं है।
नागेंद्र कुमार

1

इसके बारे में सोचने का एक तरीका यह है कि खंड जहां खंड के लिए एक अतिरिक्त फिल्टर है।

एक कहां खंड एक परिणाम से फिल्टर रिकॉर्ड किया जाता है। फ़िल्टर किसी भी समूह बनाने से पहले होता है। एक समूह से मूल्यों को फ़िल्टर करने के लिए एक HAVING क्लॉज का उपयोग किया जाता है


0

से यहाँ

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

डेटाबेस पंक्तियों पर लागू होने वाले WHERE क्लॉज़ के विपरीत


सूत्र का कहना है, "स्तंभ पदों का उपयोग पदावनत है क्योंकि वाक्यविन्यास को SQL मानक से हटा दिया गया है।" अफसोस की बात है, यह गलत है: मानक से कुछ भी कभी भी हटाया नहीं जाता है, जो विडंबना यह है कि HAVINGव्युत्पन्न तालिकाओं द्वारा इसे 'पदावनत' किए जाने के बाद भी हमारे पास दशकों हैं।
onedaywhen

थोड़ा पांडित्य लेकिन उद्धरण सही नहीं है। उदाहरण पर विचार करें SELECT 1 FROM T HAVING COUNT(*) >= 1;- GROUP BYक्लॉज में कॉलम का संदर्भ नहीं है (कुल मिलाकर कोई नहीं है) और न ही कुल कार्यों में कॉलम (क्वेरी संदर्भ कोई कॉलम नहीं है)।
onedaywhen

0

एक प्रोजेक्ट पर काम करते समय, यह मेरा सवाल भी था। जैसा कि ऊपर कहा गया है, HAVING पहले से मिले क्वेरी परिणाम पर स्थिति की जाँच करता है। लेकिन जहां हालत जबकि क्वेरी रन की जाँच के लिए है।

इसका उदाहरण देने के लिए एक उदाहरण देता हूं। मान लीजिए कि आपके पास इस तरह से एक डेटाबेस तालिका है।

usertable {इंटीनिड यूजर, डेट डेटफिल्ड, इंट डेलीइनकम}

मान लें, निम्न पंक्तियाँ तालिका में हैं:

1, 2011-05-20, 100

1, 2011-05-21, 50

1, 2011-05-30, 10

2, 2011-05-30, 10

2, 2011-05-20, 20

अब, हम चाहते हैं कि userids और sum(dailyincome)किसका होsum(dailyincome)>100

यदि हम लिखते हैं:

उपयोगकर्ता नाम का चयन करें, उपयोगकर्ता (दैनिक) से

यह एक त्रुटि होगी। सही क्वेरी होगी:

उपयोगकर्ता का चयन करें, उपयोगकर्ता से दैनिक आधार पर दैनिक आधार पर (दैनिक आधार) 100%


0

आधार तालिका में मानों की तुलना के लिए जहां क्लॉज का उपयोग किया जाता है, वहीं HAVING क्लॉज का उपयोग क्वेरी के परिणाम सेट में कुल कार्यों के परिणामों को फ़िल्टर करने के लिए किया जा सकता है !


-1

मैं एक समग्र फ़ंक्शन के परिणामों के आधार पर क्वेरी को बाध्य करने के लिए HAVING का उपयोग करता हूं। ईजी सिलेक्ट ब्लोमब्लहब्लह ग्रुप में SOMETHING द्वारा काउंट (SOMETHING)> 0


-1

यह सिर्फ यह हो सकता है कि "जहां" का विषय एक पंक्ति है, जबकि "होने" का विषय एक समूह है। क्या मैं सही हू?


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