سؤال

أحاول إنتاج جدول نتائج مع آخر تاريخ دورة مكتملة لكل رمز الدورة التدريبية ، بالإضافة إلى آخر رمز الدورة التدريبية المكتملة بشكل عام لكل موظف. أدناه هو استفساري:

SELECT employee_number,
       MAX(course_completion_date) 
           OVER (PARTITION BY course_code) AS max_course_date,
       MAX(course_completion_date) AS max_date
FROM employee_course_completion
WHERE course_code IN ('M910303', 'M91301R', 'M91301P')
GROUP BY employee_number

ينتج هذا الاستعلام الخطأ التالي:

3504 : Selected non-aggregate values must be part of the associated group

إذا قمت بإزالة خط Max () فوق (التقسيم بواسطة ...) ، فإن الاستعلام ينفذ جيدًا ، لذلك قمت بعزل المشكلة إلى هذا الخط ، ولكن بعد البحث عن هذه المنتديات والإنترنت لا يمكنني رؤية ما أقوم به " م يفعل خطأ. هل أستطيع مساعدتك؟

هل كانت مفيدة؟

المحلول

كما يقول المهور في تعليق ، لا يمكنك مزج وظائف OLAP مع وظائف إجمالية.

ربما يكون من الأسهل الحصول على تاريخ الانتهاء الأخير لكل موظف ، والانضمام إلى مجموعة بيانات تحتوي على تاريخ الانتهاء الأخير لكل من الدورات الثلاثة المستهدفة.

هذه فكرة غير مختبرة يجب أن تضعك في الطريق الصحيح:

  SELECT employee_number,
         course_code,
         MAX(course_completion_date) AS max_date,
         lcc.LAST_COURSE_COMPLETED
    FROM employee_course_completion ecc
         LEFT JOIN (
             SELECT employee_number,
                    MAX(course_completion_date) AS LAST_COURSE_COMPLETED
               FROM employee_course_completion
              WHERE course_code IN ('M910303', 'M91301R', 'M91301P')
         ) lcc
         ON lcc.employee_number = ecc.employee_number
   WHERE course_code IN ('M910303', 'M91301R', 'M91301P')
GROUP BY employee_number, course_code, lcc.LAST_COURSE_COMPLETED

نصائح أخرى

يتم حساب وظائف OLAP المنطقية بعد المجموعة بواسطة/وجودها ، بحيث يمكنك الوصول فقط إلى أعمدة في المجموعة أو الأعمدة ذات وظيفة إجمالية. يتبع يبدو غريبًا ، ولكنه SQL قياسي:

SELECT employee_number,
       MAX(MAX(course_completion_date)) 
           OVER (PARTITION BY course_code) AS max_course_date,
       MAX(course_completion_date) AS max_date
FROM employee_course_completion
WHERE course_code IN ('M910303', 'M91301R', 'M91301P')
GROUP BY employee_number, course_code

وكما يسمح Teradata بإعادة استخدام الاسم المستعار ، يعمل هذا أيضًا:

SELECT employee_number,
       MAX(max_date) 
           OVER (PARTITION BY course_code) AS max_course_date,
       MAX(course_completion_date) AS max_date
FROM employee_course_completion
WHERE course_code IN ('M910303', 'M91301R', 'M91301P')
GROUP BY employee_number, course_code

أعلم أن هذا سؤال قديم للغاية ، لكن تم طرحه من قبل شخص آخر شيئًا مشابهًا.

ليس لدي تيراتا ، لكن ألا يلي ما يلي؟

SELECT employee_number,
       course_code,
       MAX(course_completion_date)                                     AS max_course_date,
       MAX(course_completion_date) OVER (PARTITION BY employee_number) AS max_date
FROM employee_course_completion
WHERE course_code IN ('M910303', 'M91301R', 'M91301P')
GROUP BY employee_number, course_code

ال GROUP BY الآن يضمن صف واحد لكل دورة لكل موظف. هذا يعني أنك تحتاج فقط إلى مستقيم MAX() للحصول على max_course_date.

قبل الخاص بك GROUP BY كان مجرد إعطاء صف واحد لكل موظف ، و MAX() OVER() كان يحاول إعطاء نتائج متعددة لهذا الصف (واحد لكل دورة).

بدلاً من ذلك ، تحتاج الآن إلى OVER() جملة للحصول على MAX() للموظف ككل. أصبح هذا شرعيًا الآن لأن كل صف فردي يحصل على إجابة واحدة فقط (حيث يتم اشتقاقها من مجموعة فائقة ، وليس مجموعة فرعية). أيضا ، لنفس السبب ، OVER() يشير البند الآن إلى قيمة قياسية صالحة ، على النحو المحدد من قبل GROUP BY بند؛ employee_number.


ربما تكون طريقة قصيرة لقول هذا هو aggregate مع ال OVER() يجب أن يكون البند مجموعة رائعة من GROUP BY, ، وليس مجموعة فرعية.

قم بإنشاء استفسارك باستخدام GROUP BY على المستوى الذي يمثل الصفوف التي تريدها ، ثم حدد OVER() الجمل إذا كنت تريد التجميع على مستوى أعلى.

أعتقد أن هذا سيعمل على الرغم من أن هذا كان إلى الأبد.

SELECT employee_number, Row_Number()  
   OVER (PARTITION BY course_code ORDER BY course_completion_date DESC ) as rownum
FROM employee_course_completion
WHERE course_code IN ('M910303', 'M91301R', 'M91301P')
   AND rownum = 1

إذا كنت ترغب في الحصول على المعرف الأخير إذا كان التاريخ هو نفسه ، فيمكنك استخدام هذا المفتاح الأساسي الخاص بك هو معرف.

SELECT employee_number, Row_Number()  
   OVER (PARTITION BY course_code ORDER BY course_completion_date DESC, Id Desc) as rownum    FROM employee_course_completion
WHERE course_code IN ('M910303', 'M91301R', 'M91301P')
   AND rownum = 1
SELECT employee_number, course_code, MAX(course_completion_date) AS max_date
FROM employee_course_completion
WHERE course_code IN ('M910303', 'M91301R', 'M91301P')
GROUP BY employee_number, course_code
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top