max()和max()在teradata查询中通过产生错误3504分区的分区
-
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()上的(按...分区)行,则查询执行正常,因此我将问题隔离到了该行,但是在搜索这些论坛和互联网之后,我看不到我'我做错了。谁能帮忙?
解决方案
正如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
其他提示
逻辑上的OLAP函数是按/have在组之后计算的,因此您只能通过汇总函数访问组或列中的列。以下看起来很奇怪,但是标准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
我知道这是一个非常古老的问题,但是有人问我类似的事情。
我没有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 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
如果您想获得最后一个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
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