Выберите * Последний * Информация о классе для каждого студента - PullRequest
4 голосов
/ 28 января 2010

У меня есть две таблицы:

STUDENT        GRADES
----------     ----------
id             id
name           person_id
address        date
city           test_name
phone          grade

Каждый ученик будет иметь несколько записей в таблице оценок. Мне интересно, можно ли с помощью SQL (Postgres) выбрать всех учащихся вместе с их самой последней оценочной информацией. Я в основном хочу таблицу результатов, которая выглядит следующим образом, где дата, test_name и оценка для последнего результата (по дате).

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;

Ответы [ 4 ]

2 голосов
/ 28 января 2010

Я думаю, что 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 голос
/ 28 января 2010

Да, это возможно. Пункт, который вы ищете: " DISTINCT ON ". С его помощью вы можете легко выполнить запрос без вложенных выборок и нескольких сканирований одной и той же таблицы.

В документах обратите внимание на ON часть "DISTINCT ON".

1 голос
/ 28 января 2010

Хотя я не знаком с 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
                )
0 голосов
/ 28 января 2010
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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...