2010-10-01 19 views
88

बस 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) 

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

+5

कि Postgresql –

+3

MySQL में अनुमति दी गई है यह भी – Kip

+0

SQLite यह –

उत्तर

161

एसक्यूएल कार्यान्वित किया जाता है के रूप में अगर एक प्रश्न निम्न क्रम में मार डाला गया था:

    FROM खंड
  1. कहां खंड
  2. ग्रुप खंड
  3. HAVING क्लॉज़
  4. SELECT खंड
  5. द्वारा खंड
0 द्वारा आदेश

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

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

कुछ अपवाद भी हालांकि इस प्रकार हैं: MySQL और Postgres अतिरिक्त होशियारी है कि यह अनुमति देता है लगता है।

+0

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

+8

कोई विचार अगर डीबी एक ही अभिव्यक्ति को समझने के लिए पर्याप्त स्मार्ट है, तो अभिव्यक्तियों का पुनर्मूल्यांकन किए बिना चयन और समूह द्वारा खंडों में है? यानी यदि ग्रुप बाय सबस्ट्रिंग (itemName, 1,1) 'है, तो डेटाबेस पर्याप्त स्मार्ट है जो चयन खंड में सबस्ट्रिंग को पुनः कंप्यूटिंग करने के प्रदर्शन हिट नहीं लेता है? – Kip

+8

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

11

कम से कम PostgreSQL में आप स्तंभ संख्या resultset में अपने ग्रुप में BY खंड का उपयोग कर सकते हैं:

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

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

+0

'FirstLetter' द्वारा समूह के Postgresql में अनुमति दी है की अनुमति देता है की अनुमति देता है। information_schema.tables से tname समूह tname –

+1

@MichaelBuen द्वारा मेरे लिए संभावित रूप से समस्या लगता है के रूप में चयन सबस्ट्रिंग (TABLE_NAME, 1,2): बुद्धि के लिए, Postgresql में इस चलाने की कोशिश करें। एक त्वरित परीक्षण से ऐसा लगता है कि एक ही नाम के साथ उपनाम और आधार तालिका कॉलम है, तो बाद वाले को प्राथमिकता मिलती है? [एसक्यूएल फिडल] (http://sqlfiddle.com/#!15/d41d8/1920)। तो अगर उपनाम द्वारा इस समूह पर निर्भर करते हुए बाद में स्कीमा परिवर्तन चुपचाप आपकी क्वेरी तोड़ सकता है और अर्थशास्त्र बदल सकता है। –

+0

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

2

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

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

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

22

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

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

धन्यवाद, अच्छा विचार! – digz6666

0

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

8

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

SQL Server logical processing phases पर जानकारी के लिए यहां एक स्रोत है।

1

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

3

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

-- 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; 
0

मैं जवाब दे रहा हूँ नहीं क्यों यह इतना है, लेकिन केवल 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 
संबंधित मुद्दे