13

I am trying to produce a results table with the last completed course date for each course code, as well as the last completed course code overall for each employee. Below is my query:

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

This query produces the following error:

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

If I remove the MAX() OVER (PARTITION BY...) line, the query executes just fine, so I've isolated the problem to that line, but after searching these forums and the internet I can't see what I'm doing wrong. Can anyone help?

4

5 回答 5

6

正如小马在评论中所说,您不能将 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
于 2010-06-22T19:58:22.557 回答
5

逻辑上 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
于 2014-12-30T11:22:14.333 回答
1

我知道这是一个非常古老的问题,但有人问过我类似的问题。

我没有 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确保每位员工每门课程一排。这意味着您只需要顺子MAX()即可获得max_course_date.

在您GROUP BY只是为每位员工提供一排,并且MAX() OVER()试图为这一排提供多个结果(每门课程一个)之前。

相反,您现在需要该OVER()子句来获取MAX()整个员工的 。现在这是合法的,因为每一行都只得到一个答案(因为它是从超集而不是子集派生的)。同样,出于同样的原因,该OVER()子句现在引用该子句定义的有效标量值GROUP BYemployee_number.


或许一个简短的说法是aggregatewithOVER()子句必须是 的超集,而GROUP BY不是子集。

GROUP BY在表示所需行的级别创建查询,然后OVER()如果要在更高级别聚合,请指定子句。

于 2012-04-27T23:37:28.653 回答
0

我认为这将起作用,即使这是很久以前的事了。

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

如果您想在日期相同的情况下获取最后一个 Id,那么假设您的主键是 Id,您可以使用它。

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
于 2019-01-25T10:23:38.807 回答
-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
于 2019-03-12T02:56:51.183 回答