MAX () и MAX() по разделу с помощью создает ошибку 3504 в запросе Teradata
Я пытаюсь создать таблицу результатов с последней завершенной датой курса для каждого кода курса, а также последний завершенный код курса в целом для каждого сотрудника. Ниже приведен мой запрос:
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 () OVER (PARTITION BY...) строка, запрос выполняется просто отлично, поэтому я изолировал проблему с этой строкой, но после поиска на этих форумах и в Интернете я не вижу, что я делаю неправильный. Кто-нибудь может помочь?
3 ответов
Как говорит пони в комментарии, вы не можете смешивать функции 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
я знаю, что это очень старый вопрос, но мне задал кто-то другой что-то подобное.
у меня нет TeraData, но вы не можете сделать следующее?
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
теперь обеспечивает одну строку на курс на одного сотрудника. Это означает, что вам просто нужно straight MAX()
для получения max_course_date
.
перед GROUP BY
просто давал одну строку на сотрудника, и MAX() OVER()
пытался дать несколько результатов для этой одной строки (один за курс).
вместо этого вам теперь нужно OVER()
предложение, чтобы получить MAX()
для сотрудника в целом. Теперь это законно, потому что каждая отдельная строка получает только один ответ (поскольку он получен из супер-набора, а не из подмножества). Кроме того, по той же причине OVER()
предложение теперь ссылается на допустимое скалярное значение, как определено GROUP BY
пункт; employee_number
.
возможно, короткий способ сказать это было бы то, что aggregate
с OVER()
предложение должно быть супер-набором GROUP BY
, не поднабор.
создайте свой запрос с помощью GROUP BY
на уровне, представляющем нужные строки, затем укажите OVER()
предложения, если вы хотите агрегировать на более высоком уровне.
логически функции OLAP вычисляются после GROUP BY / HAVING, поэтому вы можете получить доступ только к столбцам в GROUP BY или столбцам с агрегатной функцией. Следующее выглядит странно, но является стандартным 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