Объединение в строках с максимальным значением в Access 2016 - PullRequest
0 голосов
/ 15 ноября 2018

Попытка выбрать всех студентов в Access 2016 и присоединиться к одному плану для каждого студента. Работает нормально, но выбран не самый последний план ... Если я выполнил только подзапрос для конкретного student_id, он работает, и выбран самый последний план.

SELECT dbo_Student.*, a.*
FROM dbo_Student LEFT JOIN (SELECT TOP 1 * FROM dbo_Plan ORDER BY Year 
DESC, Version DESC)  AS a ON dbo_Student.ID = a.student_id
WHERE Archived = FALSE
ORDER BY Name;

Редактировать
Это самое близкое, что я получил до сих пор, благодаря C perkins:

SELECT s.*, p.*
FROM dbo_Student s LEFT JOIN
(SELECT p1.* 
 FROM dbo_Plan p1 INNER JOIN 
      (SELECT p2.student_id, MAX(p2.ID) As MaxID
       FROM dbo_Plan p2
       GROUP BY p2.student_id
      ) pAgg
      ON p1.student_id = pAgg.student_id 
         AND p1.ID = pAgg.MaxID
) p
ON s.id = p.student_id
WHERE Archived = FALSE
ORDER BY Name;

Предполагается, что максимальный идентификатор - это самый последний План (Год DESC, Версия DESC). И это работает почти всегда, но это не безопасно.

Ответы [ 3 ]

0 голосов
/ 15 ноября 2018

Предикат TOP применяется ко всему запросу, и этот исходный подзапрос неправильно выбирал записи для каждого учащегося. Исходный запрос технически не работал должным образом, даже когда он выполнялся для определенного student_id. Возможно, он работал только потому, что у многих student_ids по совпадению был один и тот же «последний год», но этот внутренний подзапрос былвсегда выбирая одну произвольную запись , отсортированную за последний год.Мораль этого запроса: В действительном запросе есть нечто большее, чем код, который просто возвращает то, что выглядит правильно.

Следующая версия совместима с Access SQL.Самый внутренний совокупный подзапрос получает самый последний год для "каждого учащегося" (GROUP BY p2.student_id).Следующий подзапрос получает полную запись плана, которая соответствует самому последнему году.

SELECT s.*, p.*
FROM dbo_Student s LEFT JOIN
    (SELECT p1.* 
     FROM pdbo_Plan p1 INNER JOIN
          (SELECT p2.student_id, 
                 pAgg2.MaxYear,
                 MAX(pAgg2.version) As MaxVersion
           FROM pdbo_Plan p2 INNER JOIN
                (SELECT p3.student_id, MAX(p3.year) As MaxYear
                 FROM dbo_Plan p3
                 GROUP BY p3.student_id
                ) pAgg2
                ON p2.student_id = pAgg2.student_id 
                   AND p2.year = pAgg2.MaxYear
           GROUP BY p2.student_id, pAgg2.MaxYear
          ) pAgg1
          ON p1.student_id = pAgg1.student_id 
             AND p1.year = pAgg1.MaxYear
             AND p1.version = pAgg1.MaxVersion
    ) p
    ON s.id = p.student_id
WHERE Archived = FALSE
ORDER BY Name;
0 голосов
/ 15 ноября 2018

Учитывая, что ваш исходный запрос подразумевает, что может быть несколько Versions для одного Year (ORDER BY Year DESC, Version DESC); Я бы предложил следующее:

select dbo_student.*, b.*
from
    dbo_student left join
    (
        select a.* from dbo_plan a inner join
        (
            select q.student_id, q.year, max(q.version) as v
            from dbo_plan q inner join
            (
                select p.student_id, max(p.year) as y
                from dbo_plan p
                group by p.student_id
            ) s on q.student_id = s.student_id and q.year = s.y
            group by q.student_id, q.year
        ) t on
        a.student_id = t.student_id and 
        a.year = t.year and
        a.version = t.v
    ) b on dbo_student.id = b.student_id
where 
    archived = false
order by 
    name

Самый внутренний запрос получает максимум Year на Student_ID, родительский запрос затем получает максимум Version для такого Year на Student_ID, к которому присоединяется исходная таблица, так что все поля могут быть выход.

0 голосов
/ 15 ноября 2018

Я думаю, что вы хотите:

SELECT s.*, p.*
FROM dbo_Student s LEFT JOIN
     dbo_Plan p
     ON p.student_id = s.id AND
        p.year = (SELECT MAX(p1.year)
                  FROM dbo_Plan p1
                  WHERE p1.student_id = p.student_id
                 )
WHERE Archived = FALSE
ORDER BY Name;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...