2012-07-06 18 views
8

में देखते हुए शामिल करेंकुशलतापूर्वक कॉलम नहीं एसक्यूएल के समूह के आधार पर क्वेरी

तालिका A

Id INTEGER 
Name VARCHAR(50) 

टेबल बी

Id INTEGER 
FkId INTEGER ; Foreign key to Table A 

मैं हर FkId मूल्य की occurrances गिनती करना चाहते हैं :

SELECT FkId, COUNT(FkId) 
FROM B 
GROUP BY FkId 

अब मैं बस Table A से नाम आउटपुट करना चाहता हूं।

यह काम नहीं करेगा:

SELECT FkId, COUNT(FkId), a.Name 
FROM B b 
INNER JOIN A a ON a.Id=b.FkId 
GROUP BY FkId 

क्योंकि a.NameGROUP BY खंड में निहित नहीं है (is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause त्रुटि पैदा करता है)।

बिंदु इस

FkId Count Name 
1  42  Ronald 
2  22  John 

कि त्रुटि संदेश के लिए इतने पर काफी कुछ भी मैच नहीं है, लेकिन कुछ जैसे की तरह उत्पादन को यह

FkId Count 
1  42 
2  25 

तरह उत्पादन से स्थानांतरित करने के लिए है https://stackoverflow.com/a/6456944/141172 की टिप्पणियां हैं जैसे "तालिका के बजाय 3 स्कैन जेनरेट करेंगी, इसलिए स्केल नहीं होगी"। क्वेरी उत्पादन में:

मैं कैसे कुशलतापूर्वक में शामिल हो गए Table B (FkId करने के लिए 1 संबंध है जो एक 1 है) से एक क्षेत्र शामिल हैं कर सकते हैं?

+0

क्या आप कुछ नमूना डेटा और वांछित परिणाम दिखा सकते हैं? मुझे FKId प्रति एक से अधिक अद्वितीय नाम होने पर कठिनाई हो रही है। –

+0

FkId प्रति केवल एक अद्वितीय नाम होगा। बिंदु सिर्फ एफकेआईडी के साथ नाम दिखाने के लिए है, इसलिए परिणाम देखने वाले उपयोगकर्ता को "व्यक्ति 1 42 बार दिखाया गया" नहीं दिखता है बल्कि यह "व्यक्ति 1, जिसका नाम रोनाल्ड है, 42 बार दिखाया गया है" देखता है। –

+1

तो समूह में नाम क्यों न जोड़ें? –

उत्तर

12

आप कुछ इस तरह की कोशिश कर सकते Table A पर और अपने अंतिम परिणाम सेट में Table A से कुछ और कॉलम लें।

+0

यह उस समाधान के समान ही है जो मैंने लिंक किया था, जिसमें टिप्पणी थी और 1 के बजाय तालिका पर 3 स्कैन उत्पन्न करेगा, इसलिए स्केल नहीं होगा। क्या यह समाधान वास्तव में 3 टेबल स्कैन करेगा क्योंकि टिप्पणीकर्ता सुझाव देता है? –

+5

@EricJ .: अच्छी तरह से - क्वेरी की प्रतिलिपि बनाएँ, इसे अपने SQL सर्वर एमजीएमटी स्टूडियो में चलाएं और "वास्तविक निष्पादन योजना" चालू हो, और आप देखेंगे कि ** नहीं ** यह ** ** ** तीन टेबल स्कैन नहीं करेगा .....आपके द्वारा लिंक किए गए उत्तर में टिप्पणी सही है क्योंकि पूछताछ ** दो अतिरिक्त ** '(चयन ....)' subqueries - ** वे ** प्रत्येक तालिका स्कैन जोड़ देंगे (** नहीं ** समूह का उपयोग करने के लिए सीटीई का उपयोग किया जाता है!) प्रदर्शन का निदान करने के लिए वास्तविक निष्पादन योजना का उपयोग करने के लिए –

+1

+1। :-) –

3

क्या आपने समूह में फ़ील्ड जोड़ने का प्रयास किया था? अपने Table B पर भरोसा समूह को संभालने के लिए

;WITH GroupedData AS 
    (
     SELECT FkId, COUNT(FkId) As FkCount 
     FROM B 
     GROUP BY FkId 
    ) 
    SELECT gd.*, a.Name 
    FROM GroupedData gd 
    INNER JOIN dbo.A ON gd.FkId = A.FkId 

एक CTE (आम तालिका अभिव्यक्ति) बनाएं /, और फिर (FkId प्रति एक पंक्ति) कि परिणाम में शामिल होने:

SELECT FkId, COUNT(FkId), a.Name 
FROM B b 
INNER JOIN A a ON a.Id=b.FkId 
GROUP BY FkId,a.Name 
0
select t3.Name, t3.FkId, t3.countedFkId from (a t1 
    join (select t2.FkId, count(FkId) as countedFkId from b t2 group by t2.FkId) 
    on t1.Id = t2.FkId) t3; 
+1

कृपया '{}' नहीं 'का उपयोग करें कोड ब्लॉक हाइलाइट करें। और कैरिज रिटर्न से डरो मत। इसके अलावा मुझे नहीं लगता कि यह क्वेरी पार्स (व्युत्पन्न तालिका को उपनाम की आवश्यकता है)। –

+0

ओह, सलाह के लिए धन्यवाद। अभी भी वाक्यविन्यास के लिए नया :) और मुझे लगता है कि आप व्युत्पन्न तालिका के लिए उपनाम की आवश्यकता के बारे में सही हैं। – germi

संबंधित मुद्दे