एसक्यूएल - समूह द्वारा उपनाम का उपयोग करना


143

SQL सिंटैक्स के बारे में बस उत्सुक। तो अगर मेरे पास है

SELECT 
 itemName as ItemName,
 substring(itemName, 1,1) as FirstLetter,
 Count(itemName)
FROM table1
GROUP BY itemName, FirstLetter

यह गलत होगा क्योंकि

GROUP BY itemName, FirstLetter 

वास्तव में होना चाहिए

GROUP BY itemName, substring(itemName, 1,1)

लेकिन हम केवल सुविधा के लिए पूर्व का उपयोग क्यों नहीं कर सकते?


13
Postgresql में इसकी अनुमति है
माइकल बुएन

7
MySQL यह भी अनुमति देता है
किप

1
आप किस rdbms के बारे में बात कर रहे हैं?
शिवांगिनी

जवाबों:


292

एसक्यूएल को लागू किया जाता है जैसे कि निम्नलिखित क्रम में एक क्वेरी निष्पादित की गई थी:

  1. खंड से
  2. कहां कारण
  3. समूह द्वारा खंड
  4. हवलदार खंड
  5. खंड का चयन करें
  6. खंड द्वारा आदेश

अधिकांश रिलेशनल डेटाबेस सिस्टम के लिए, यह आदेश बताता है कि कौन से नाम (कॉलम या उपनाम) मान्य हैं क्योंकि उन्हें पिछले चरण में पेश किया जाना चाहिए।

तो Oracle और SQL सर्वर में, आप समूह BY खंड में एक शब्द का उपयोग नहीं कर सकते हैं जिसे आप चयन खंड में परिभाषित करते हैं क्योंकि समूह BY को SELECT खंड से पहले निष्पादित किया जाता है।

हालांकि कुछ अपवाद हैं: MySQL और Postgres में अतिरिक्त स्मार्टनेस है जो इसे अनुमति देता है।


3
मुझे यह स्पष्टीकरण पसंद है। हालांकि मैं यह अनुमान नहीं लगा सकता कि सिंटैक्टिक शुगर के रूप में इसे इंजन में जोड़ना कितना मुश्किल है।
हौस्टे

11
किसी भी विचार अगर DB एक ही अभिव्यक्ति का एहसास करने के लिए पर्याप्त स्मार्ट है, तो अभिव्यक्ति के पुनर्मूल्यांकन के बिना चयन और समूह द्वारा खंड में है? यानी अगर वहाँ है GROUP BY substring(itemName, 1,1), तो डेटाबेस काफी स्मार्ट है जो सेलेक्ट क्लॉज में सब्स्क्राइब को फिर से प्रदर्शित करने के लिए प्रदर्शन हिट नहीं लेता है?
किप

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

6
प्रश्न के साथ निष्पादन आदेश का क्या करना है? यह ऐसा नहीं है कि पूछने वाला COUNT () पर ग्रुप बाय की कोशिश कर रहा था। वास्तव में, पूछे जाने वाले प्रश्न के रूप में MySQL में ठीक काम करता है और संभवतः PostgreSQL टिप्पणियों में बताया गया है।

1
Mysql के लिए, बिटमेस्क में ONLY_FULL_GROUP_BY को sql_modeशामिल नहीं करने के लिए, ऑप्टिमाइज़र के पास क्लाज़ में अलियास के विविध / अलग - अलग उपयोग के साथ बेहतर परिणाम देने का मौका है । HAVING
ड्रयू

28

आप हमेशा एक उप-वर्ग का उपयोग कर सकते हैं ताकि आप उपनाम का उपयोग कर सकें; बेशक, प्रदर्शन की जांच करें (संभव है कि डीबी सर्वर दोनों एक ही चलेगा, लेकिन कभी सत्यापित करने के लिए दर्द नहीं होता):

SELECT ItemName, FirstLetter, COUNT(ItemName)
FROM (
    SELECT ItemName, SUBSTRING(ItemName, 1, 1) AS FirstLetter
    FROM table1
    ) ItemNames
GROUP BY ItemName, FirstLetter

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

1
@ रोलैंड लेकिन उस मामले में निष्पादन योजना में अलग नहीं है। क्या कोई अन्य प्रदर्शन विचार है?
गुइडो मोचा

@Roland, सहसंबद्ध सबक्वेरी या अन्य वाक्य रचना छोरों या पंक्ति-दर-पंक्ति व्यवहार करने के लिए सुराग बचा जाना चाहिए कि, और कितना गहरा आप नेस्टेड सबक्वेरी के साथ जाना चाहिए की एक सीमा होती है, लेकिन यह आम तौर पर है सच नहीं है कि सबक्वेरी नेतृत्व खराब प्रदर्शन के लिए। इस मामले में जैसा कि क्रिस ने कहा है, आप निष्पादन योजना (AKA क्वेरी प्लान, व्याख्या योजना) को सत्यापित कर सकते हैं कि दोनों उपकुंजी के साथ और उसके बिना तुलना करें, और देखें कि क्या वास्तव में कोई अंतर है। बहुत अधिक हर डेटाबेस इंजन आपकी क्वेरी को फिर से लिख देगा ताकि आप पूरी तरह से नियंत्रण में न रहें कि क्या निष्पादित होता है। यह घोषणात्मक वाक्यविन्यास की बात है।
दावोस

16

कम से कम PostgreSQL में आप परिणाम समूह में कॉलम नंबर का उपयोग अपने ग्रुप BY क्लॉज में कर सकते हैं:

SELECT 
 itemName as ItemName,
 substring(itemName, 1,1) as FirstLetter,
 Count(itemName)
FROM table1
GROUP BY 1, 2

निश्चित रूप से यह दर्द होने लगता है यदि आप यह अंतःक्रियात्मक रूप से कर रहे हैं और आप परिणाम में कॉलम की संख्या या क्रम को बदलने के लिए क्वेरी को संपादित करते हैं। फिर भी।


GROUP BY FirstLetterPostgresql में अनुमति है। बुद्धि के लिए, Postgresql में इसे चलाने का प्रयास करें: substring (table_name, 1,2) को tname के रूप में tname के रूप में tname द्वारा चुनें_नाम
माइकल

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

@MartinSmith को अब केवल इतना ही पता था कि वह एक गोत्र है, उस का उपयोग करने से बचना चाहिए, धन्यवाद। यह देखते हुए कि PostgreSQL उस शॉर्टकट की अनुमति देता है, उन्हें उपनाम को प्राथमिकता देनी चाहिए, अन्यथा उन्हें उस शॉर्टकट को बिल्कुल भी अनुमति नहीं देनी चाहिए।
माइकल बुएन

यह PostgreSQL डिजाइनरों द्वारा एक भयानक विचार था। जैसे ही आप GROUP BYकिसी भी अभिव्यक्ति की कोशिश करते हैं, जिसमें कुल कार्य या विंडो फ़ंक्शंस होते हैं, जो "स्पष्ट रूप से" काम नहीं करता है, यह भ्रामक है ।
लुकास ईडर

13

SQL सर्वर प्रसंस्करण के तार्किक क्रम के कारण आपको ग्रुप बाय क्लाज में उपनाम का संदर्भ देने की अनुमति नहीं देता है। ग्रुप BY क्लॉज को सेलेक्ट क्लॉज से पहले प्रोसेस किया जाता है, इसलिए ग्रुप बाय क्लॉज का मूल्यांकन करने पर उपनाम का पता नहीं चलता है। यह भी बताता है कि आप ORDER BY क्‍लॉज में उपनाम का उपयोग क्‍यों कर सकते हैं।

यहां SQL सर्वर लॉजिकल प्रोसेसिंग चरणों की जानकारी के लिए एक स्रोत है


8

मैं जवाब नहीं दे रहा हूं कि ऐसा क्यों है, लेकिन केवल CROSS APPLYउपनाम बनाने के लिए एसक्यूएल सर्वर में उस सीमा के आसपास एक रास्ता दिखाना चाहता था । आप तब इसका उपयोग GROUP BYक्लॉज में करते हैं , जैसे:

SELECT 
 itemName as ItemName,
 FirstLetter,
 Count(itemName)
FROM table1
CROSS APPLY (SELECT substring(itemName, 1,1) as FirstLetter) Alias
GROUP BY itemName, FirstLetter

4

समूह द्वारा उर्फ ​​का उपयोग करने वाली सावधानी (सेवाओं के लिए जो इसका समर्थन करती हैं, जैसे पोस्टग्रैज) अनपेक्षित परिणाम हो सकती हैं। उदाहरण के लिए, यदि आप एक उपनाम बनाते हैं जो पहले से ही आंतरिक विवरण में मौजूद है, तो समूह बाय ने आंतरिक क्षेत्र का नाम चुना है।

-- Working example in postgres
select col1 as col1_1, avg(col3) as col2_1
from
    (select gender as col1, maritalstatus as col2, 
    yearlyincome as col3 from customer) as layer_1
group by col1_1;

-- Failing example in postgres
select col2 as col1, avg(col3)
from
    (select gender as col1, maritalstatus as col2,
    yearlyincome as col3 from customer) as layer_1
group by col1;

3

कुछ DBMS आपको पूरी अभिव्यक्ति को दोहराने के बजाय एक उपनाम का उपयोग करने देंगे।
टेराडाटा एक ऐसा उदाहरण है।

मैं इस SO प्रश्न में प्रलेखित कारणों के लिए विधेयक द्वारा अनुशंसित अध्यादेशीय स्थिति संकेतन से बचता हूं ।

आसान और मजबूत विकल्प यह है कि ग्रुप बाय क्लॉज में हमेशा अभिव्यक्ति को दोहराया जाए।
DRY SQL पर लागू नहीं होता है।


1

SQLite में एक दृश्य से परिणाम समूहीकृत करते समय उपनाम का उपयोग करने से सावधान रहें। यदि किसी अन्य अंतर्निहित तालिकाओं के स्तंभ नाम के समान (विचारों पर) एक जैसा है तो आपको अप्रत्याशित परिणाम प्राप्त होंगे।


0

दिन में वापस मैंने पाया कि आरडीबी, पूर्व डीईसी उत्पाद जो अब ओरेकल द्वारा समर्थित है, कॉलम अलियास को ग्रुप बीवाई में उपयोग करने की अनुमति देता है। संस्करण 11 के माध्यम से मेनस्ट्रीम ओरेकल, कॉलम अलियास को ग्रुप बीवाई में उपयोग करने की अनुमति नहीं देता है। निश्चित नहीं है कि Postgresql, SQL Server, MySQL, आदि क्या अनुमति देगा या नहीं। YMMV।

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