2010-08-05 12 views
5

मैं निम्न क्वेरी निष्पादित करने के लिए कोशिश कर रहा हूँ, लेकिन मुझे लगता है कि यह कहते हुए एक रनटाइम त्रुटि प्राप्त में एकल पंक्ति कुल उप क्वेरी के साथ समस्या:एसक्यूएल उन्नत क्वेरी - चयन खंड

"The column is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause." 

लाइन नंबर के नीचे दो में से एक है कि उपरोक्त त्रुटि के साथ विफल रहता है। मुझे समझ में नहीं आ रहा है कि यह क्वेरी निष्पादित नहीं होती है क्योंकि लाइन दो में कोई समूहिंग की आवश्यकता नहीं है क्योंकि आउटपुट सिर्फ गिनती है (*), इस काम को पाने के लिए मुझे क्या बदलने की आवश्यकता है, इस बारे में कोई संकेत है?

SELECT @lessonPlans = COUNT(*) 
, @lessonPlanResources = (SELECT COUNT(*) FROM dbo.LessonPlanResource lpr where lpr.LessonPlanId = a.LessonPlanId) 
FROM 
( 
    SELECT DISTINCT lpt.LessonPlanId 
    FROM dbo.LearningTargetBreakout ltb 
    JOIN dbo.LessonPlanLearningTarget lpt 
     on lpt.LearningTargetId = ltb.LearningTargetId 
    WHERE (CASE 
      WHEN ltb.LearningTargetId = @learningTargetId and @learningTargetId is not null THEN 1 
      WHEN ltb.CategoryId = @categoryId and @categoryId is not null THEN 1 
      WHEN ltb.Grade = @grade and @grade is not null THEN 1 
      WHEN ltb.SubjectId = @subjectId and @subjectId is not null THEN 1 
      ELSE 0 END) = 1 
) a 

[संपादित करें]

Zeb के समाधान का एक मामूली बदलाव का उपयोग करना - यहाँ संशोधित कोड है कि मैं का उपयोग कर, जो समुच्चय के साथ एक पंक्ति पैदावार है, जो है जो मैं के बाद समाप्त हो गया था है।

SELECT @lessonPlans = ISNULL(COUNT(*), 0) 
     , @lessonPlanResources = ISNULL(SUM(a.ResCount), 0) 
FROM 
( 
    SELECT DISTINCT lpt.LessonPlanId, lpr.ResCount 
    FROM dbo.LearningTargetBreakout ltb 
    JOIN dbo.LessonPlanLearningTarget lpt 
     on lpt.LearningTargetId = ltb.LearningTargetId 
    JOIN (SELECT LessonPlanId, COUNT(*) ResCount FROM dbo.LessonPlanResource lpr GROUP BY LessonPlanId) lpr 
     ON lpr.LessonPlanId = lpt.LessonPlanId   
    WHERE (CASE 
      WHEN ltb.LearningTargetId = @learningTargetId and @learningTargetId is not null THEN 1 
      WHEN ltb.CategoryId = @categoryId and @categoryId is not null THEN 1 
      WHEN ltb.GradeId = @grade and @grade is not null THEN 1 
      WHEN ltb.SubjectId = @subjectId and @subjectId is not null THEN 1 
      ELSE 0 END) = 1 
) a 
+0

क्या गिनती (*) और नहीं गिनती (lpr.lessionplanid) – Perpetualcoder

+0

करने से में आंतरिक क्वेरी के उत्पादन के बाद से पीछे अपने कारण खंड केवल LessonPlanId फ़ील्ड है, यह वास्तव में गिनती टाइप करने जैसा ही है (lpr.lessionplanid) अगर मुझे गलत नहीं लगता है। – James

उत्तर

4

मेरा अनुमान है कि @lessonPlanResources LessonPlanId से जुड़ा हुआ है, जो कुल नहीं है।

मेरा समाधान उस सबटेबल में शामिल होना होगा, और लौटा कॉलम इसके COUNT हो।

SELECT @lessonPlans = COUNT(*) 
, @lessonPlanResources = SUM(zlpr.reses) 
FROM 
( 
    SELECT DISTINCT lpt.LessonPlanId, zlpr.reses 
    FROM dbo.LearningTargetBreakout ltb 
    JOIN dbo.LessonPlanLearningTarget lpt 
     on lpt.LearningTargetId = ltb.LearningTargetId 
    JOIN (SELECT LessonPlanId, COUNT(*) reses FROM dbo.LessonPlanResource lpr) zlpr 
     ON zlpr.LessonPlanId = lpt.LessonPlanId 
    WHERE (CASE 
      WHEN ltb.LearningTargetId = @learningTargetId and @learningTargetId is not null THEN 1 
      WHEN ltb.CategoryId = @categoryId and @categoryId is not null THEN 1 
      WHEN ltb.Grade = @grade and @grade is not null THEN 1 
      WHEN ltb.SubjectId = @subjectId and @subjectId is not null THEN 1 
      ELSE 0 END) = 1 
) a 
+0

अच्छी चाल, यह समाधान मैं समाप्त हो गया था। – James

3

आपका count(*) एक समग्र समारोह है और @lessonPlanResources के लिए अभिव्यक्ति नहीं है (भले ही यह COUNT(*) साथ एक प्रश्न है)। इसलिए, अभिव्यक्ति को ग्रुप बाय क्लॉज में शामिल किया जाना चाहिए।

आप सामान्य तालिका अभिव्यक्तियों (सीटीई) का उपयोग कर सकते हैं, जो पठनीयता के साथ भी मदद कर सकता है।

WITH LPR_CTE as 
    (
    SELECT LessonPlanId, COUNT(*) as LessonPlanResourcesCount 
    FROM dbo.LessonPlanResource 
    GROUP BY LessonPlanId 
    ), 

    LP_CTE(
    SELECT lpt.LessonPlanId, COUNT(*) as LessonPlansCount 
    FROM dbo.LearningTargetBreakout ltb 
    JOIN dbo.LessonPlanLearningTarget lpt 
     on lpt.LearningTargetId = ltb.LearningTargetId 
    WHERE (CASE 
      WHEN ltb.LearningTargetId = @learningTargetId and @learningTargetId is not null THEN 1 
      WHEN ltb.CategoryId = @categoryId and @categoryId is not null THEN 1 
      WHEN ltb.Grade = @grade and @grade is not null THEN 1 
      WHEN ltb.SubjectId = @subjectId and @subjectId is not null THEN 1 
      ELSE 0 END) = 1 
    ) 

SELECT @lessonPlans = LP_CTE.LessonPlansCount 
    , @lessonPlanResources = LPR_CTE.LessonPlanResourcesCount 
FROM LP_CTE 
JOIN LPR_CTE on LP_CTE.LessonPlanId = LPR_CTE.LessonPlanId 
1

आप GROUP BY a.LessonPlanId करने की आवश्यकता होगी और संभवत: तुम क्या करने की कोशिश कर रहे हैं कि वास्तव में क्या पर निर्भर करता है COUNT(*) OVER() करने के लिए पहले COUNT(*) बदल जाते हैं।

लेकिन संभवतया उन परिणामों की कई पंक्तियां देगी जिन्हें आप स्केलर चर के एक सेट को असाइन करने का प्रयास कर रहे हैं। हैं जो आप बिल्कुल करने की कोशिश कर रहे हैं?

+0

+1 बाहरी क्वेरी के अंत तक एक समूह जोड़ना जैसा आपने सुझाव दिया है समस्या को ठीक करने के लिए लगता है। लेकिन तार्किक रूप से मैं सिर्फ यह नहीं देख रहा हूं कि यह कैसे समझ में आता है। क्या यह सिर्फ उन विक्रेताओं में से एक है जो गोचाचा है? – James

+0

@ जेम्स - MySQL यह लागू नहीं करता है लेकिन अन्य सभी करते हैं। मुझे लगता है कि आपको अभी भी समस्या हो रही है हालांकि स्केलर वैरिएबल में कई पंक्तियां प्राप्त करने की कोशिश कर रहा है (मुझे लगता है कि आप संभवतः संसाधित अंतिम समूह के मूल्य को पकड़कर उनके साथ समाप्त होने जा रहे हैं) –

+0

मेरा इरादा था पंक्तियों को चर के रूप में केवल समेकित करने के लिए। – James

0

मुद्दा यह है कि आप इस सबक्वेरी के साथ एक समूह समारोह (गिनती) का उपयोग कर रहे हैं: LPR dbo.LessonPlanResource से COUNT का चयन करें (*) जहां lpr.LessonPlanId = a.LessonPlanId

हालांकि करने के लिए संदर्भ a.LessonPlanId एक गैर-समूह वाला क्षेत्र है। अपनी क्वेरी को समूहित करें और आप उस फ़ील्ड को संदर्भित कर सकते हैं।

इस प्रयास करें:

SELECT @lessonPlans = COUNT(*) 
, @lessonPlanResources = (SELECT COUNT(*) FROM dbo.LessonPlanResource lpr where lpr.LessonPlanId = a.LessonPlanId) 
FROM 
( 
    SELECT DISTINCT lpt.LessonPlanId 
    FROM dbo.LearningTargetBreakout ltb 
    JOIN dbo.LessonPlanLearningTarget lpt 
     on lpt.LearningTargetId = ltb.LearningTargetId 
    WHERE (CASE 
      WHEN ltb.LearningTargetId = @learningTargetId and @learningTargetId is not null THEN 1 
      WHEN ltb.CategoryId = @categoryId and @categoryId is not null THEN 1 
      WHEN ltb.Grade = @grade and @grade is not null THEN 1 
      WHEN ltb.SubjectId = @subjectId and @subjectId is not null THEN 1 
      ELSE 0 END) = 1 
) a 
GROUP BY a.LessonPlanID 
+0

धन्यवाद, क्या यह सुझाव देता है कि मुझे अब क्लॉज की आंतरिक क्वेरी में विशिष्ट करने की आवश्यकता नहीं है जहां मैं डुप्लिकेट की अपेक्षा करता हूं? – James

+0

नहीं, यह आवश्यक नहीं होगा क्योंकि समूह द्वारा किसी भी डुप्ली को समाप्त किया जाएगा। – kniemczak

0
  • अपने बाहरी चयन से COUNT निकाला जा रहा है।
  • में COUNT DISTINCT का उपयोग करते हुए अपने भीतर का चयन

SELECT 
    @lessonPlans = a.B, 
    @lessonPlanResources = (SELECT COUNT(*) FROM dbo.LessonPlanResource lpr where lpr.LessonPlanId = a.LessonPlanId) 
FROM 
( 
    SELECT COUNT (DISTINCT, lpt.LessonPlanId) AS B 
    FROM dbo.LearningTargetBreakout ltb 
    JOIN dbo.LessonPlanLearningTarget lpt 
     on lpt.LearningTargetId = ltb.LearningTargetId 
    WHERE (CASE 
      WHEN ltb.LearningTargetId = @learningTargetId and @learningTargetId is not null THEN 1 
      WHEN ltb.CategoryId = @categoryId and @categoryId is not null THEN 1 
      WHEN ltb.Grade = @grade and @grade is not null THEN 1 
      WHEN ltb.SubjectId = @subjectId and @subjectId is not null THEN 1 
      ELSE 0 END) = 1 
) a 
+0

यह काम नहीं प्रतीत होता है। – James

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