我有两张桌子:
STUDENT GRADES
---------- ----------
id id
name person_id
address date
city test_name
phone grade
每个学生将在成绩表中有多个条目。我想知道是否可以使用SQL(Postgres)选择所有学生以及他们的最新成绩信息。我基本上想要一个如下所示的结果表,其中date,test_name和grade是最新结果(按日期)。
LATEST_GRADES
----------------
id
name
address
city
phone
grade_id
date
test_name
grade
非常感谢任何帮助,谢谢。
编辑:添加解决方案查询
SELECT * FROM
students s
JOIN (SELECT DISTINCT ON (person_id) person_id, date, test_name, grade
FROM grades
ORDER BY person_id, date DESC) g
ON s.id = g.person_id;
答案 0 :(得分:2)
我认为Postgre支持窗口函数,因此您应该可以执行类似
的操作SELECT *
FROM person p
JOIN grades g ON grades.person_id = p.id
WHERE row_number() OVER (PARTITION BY g.person_id ORDER BY g.date DESC) = 1
编辑:显然在where子句中不支持窗口函数(应该知道这个,因为它有意义)。然而,这不是一个无法解决的问题:
SELECT *
FROM person p
JOIN (SELECT person_id, <other_fields>, row_number() OVER (PARTITION BY person_id ORDER BY date DESC) AS rn FROM grades) g
WHERE g.rn = 1
如果您的数据很大,请检查执行计划。
答案 1 :(得分:1)
虽然我不熟悉Postgres,但我在与Oracle合作时做了很多这样的事情。也许下面的查询会有所帮助。
select p.id,
p.name,
p.address,
p.city,
p.phone,
g.date,
g.test_name,
g.grade
from person p,
grades g
where p.id = g.person_id
and g.date = (select max(g2.date)
from grades g2
where g2.id = g.id
)
答案 2 :(得分:1)
是的,这是可能的。您正在寻找的条款是“DISTINCT ON”。有了它,您可以轻松地进行查询,而无需对同一个表进行子选择和多次扫描。
在文档中,请注意“DISTINCT ON”的 ON 部分。
答案 3 :(得分:0)
select
S.id,
S.name,
S.address,
S.city,
S.phone,
G.id as grade_id,
G.date,
G.test_name,
G.grade
from
Grades G,
Student S,
(select S.id as studentid, max(date) as latest_grade_date
from student S , grades G where s.id = g.person_id) Q
WHERE
G.person_id = Q.studentid
AND S.id = Q.studentid
AND G.date = Q.latest_grade_date
AND S.id = G.person_id