MAX()和MAX()OVER PARTITION BY在Teradata Query中产生错误3504

dne*_*er3 8 sql aggregate-functions teradata database-partitioning

我正在尝试生成一个结果表,其中包含每个课程代码的最后完成课程日期,以及每位员工最后完成的课程代码.以下是我的查询:

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
Run Code Online (Sandbox Code Playgroud)

此查询产生以下错误:

3504 : Selected non-aggregate values must be part of the associated group
Run Code Online (Sandbox Code Playgroud)

如果我删除MAX()OVER(PARTITION BY ...)行,查询执行得很好,所以我已经将问题隔离到该行,但在搜索这些论坛和互联网后,我看不到我的意思我做错了.有人可以帮忙吗?

dno*_*eth 10

逻辑上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
Run Code Online (Sandbox Code Playgroud)

由于 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
Run Code Online (Sandbox Code Playgroud)


ber*_*nie 5

正如Ponies在评论中所说,您不能将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
Run Code Online (Sandbox Code Playgroud)