Max () و Max () فوق التقسيم بواسطة Error 3504 في استعلام Teradata
-
29-09-2019 - |
سؤال
أحاول إنتاج جدول نتائج مع آخر تاريخ دورة مكتملة لكل رمز الدورة التدريبية ، بالإضافة إلى آخر رمز الدورة التدريبية المكتملة بشكل عام لكل موظف. أدناه هو استفساري:
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