SQL Присоединиться к последней записи в MS ACCESS

#sql #ms-access #join #greatest-n-per-group

#sql #ms-access #Присоединиться #наибольшее число пользователей на группу

Вопрос:

Я хочу объединить таблицы в MS Access таким образом, чтобы он извлекал только последнюю запись из одной из таблиц. Я просмотрел другие решения, доступные на сайте, но обнаружил, что они работают только для других версий SQL. Вот упрощенная версия моих данных:

Таблица PatientInfo:

      ----- ------ 
    | ID  | Name |
     ----- ------ 
    |  1  | John |
    |  2  | Tom  |
    |  3  | Anna |
     ----- ------ 
 

Таблица встреч

      ---- ----------- 
    | ID |   Date    |
     ---- ----------- 
    |  1 | 5/5/2001  |
    |  1 | 10/5/2012 |
    |  1 | 4/20/2018 |
    |  2 | 4/5/1999  |
    |  2 | 8/8/2010  |
    |  2 | 4/9/1982  |
    |  3 | 7/3/1997  |
    |  3 | 6/4/2015  |
    |  3 | 3/4/2017  |
     ---- ----------- 
 

И вот упрощенная версия результатов, которые мне нужны после объединения:

      ---- ------ ------------ 
    | ID | Name |    Date    |
     ---- ------ ------------ 
    |  1 | John |  4/20/2018 |
    |  2 | Tom  |  8/8/2010  |
    |  3 | Anna |  3/4/2017  |
     ---- ------ ------------ 
 

Заранее спасибо за чтение и за вашу помощь.

Ответ №1:

Вы можете использовать агрегирование и JOIN :

 select pi.id, pi.name, max(a.date)
from appointments as a inner join
     patientinfo as pi
     on a.id = pi.id
group by pi.id, pi.name;
 

Ответ №2:

что-то вроде этого: выберите P.ID , P.name , макс (A.Дата) как Dt из PatientInfo P внутренние назначения соединения A на P.ID=A.Группировка идентификаторов по P.ID , P.name

Ответ №3:

Оба ответа Bing и Гордона работают, если вашей сводной таблице требуется только одно поле (максимальное (дата)), но становится сложнее, если вы также хотите сообщить о других полях из объединенной таблицы, поскольку вам нужно будет включить их либо в качестве агрегированного поля, либо сгруппировать по ним. Например, если вы хотите, чтобы ваше резюме также включало оценку, которую они получили на последнем приеме, ГРУППИРОВАТЬ ПО-другому.

Более универсальной структурой может быть что-то вроде

 SELECT Patient.ID, Patient.Name, Appointment.Date, Appointment.Assessment
FROM Patient INNER JOIN Appointment ON Patient.ID=Appointment.ID
WHERE Appointment.Date = (SELECT Max(Appointment.Date) FROM Appointment WHERE Appointment.ID = Patient.ID)
;
 

Кроме того, вы можете подумать, следует ли использовать поле с именем ‘ID’ для ссылки на идентификатор другой таблицы (в данном случае Apppintment.Поле ID относится к Patient.ID ). Вы можете сделать свою базу данных более читаемой, если оставите поле «ID» в качестве идентификатора, специфичного для этой таблицы, и будете ссылаться на это поле в других таблицах как OtherTableID или аналогичный, т.Е. PatientID в данном случае. Или пройдите весь путь и включите имя фактической таблицы в ее собственное поле ID.

Отредактировано после комментария:

Не совсем уверен, почему это приведет к сбою. Я только что выполнил эквивалентный запрос к имеющимся у меня 2 таблицам, каждая из которых содержит около 10 000 записей, и это было довольно мгновенно. Являются ли ваши поля идентификаторов (i) уникальными номерами и (ii) индексированными? Другая структура, которая должна делать то же самое (адаптированная для ваших имен полей и предполагающая, что в назначениях есть поле идентификатора, которое является уникальным), будет выглядеть примерно так:

 SELECT PatientInfo.UID, PatientInfo.Name, Appointments.StartDateTime, Appointments.Assessment
FROM PatientInfo INNER JOIN Appointments ON PatientInfo_UID = Appointments.PatientFID
WHERE Appointments.ID = (SELECT TOP 1 ID FROM Appointments WHERE Appointments.PatientFID = PatientInfo_UID ORDER BY StartDateTime DESC)
;
 

Но это начинает выглядеть немного надуманным. Для моих данных они оба дают одинаковый результат (как и должны!) и оба почти мгновенные.
Всегда сложно устранить неполадки при сбое Access — я думаю, вы не видите кодов ошибок или подобных? Это относится к собственной базе данных .accdb или к другому серверу?

Комментарии:

1. Мне нравится предложенный вами запрос, поскольку я хотел бы сообщить и о других полях, но я работаю с более чем 60 000 строк, и ваше предложение приводит к сбою Access. Есть предложения? Вот код: SELECT PatientInfo.Patient_UID, PatientInfo.LastName, PatientInfo.FirstName, PatientInfo.Email, PatientInfo.Deceased, Appointments.StartDateTime FROM PatientInfo INNER JOIN Appointments ON PatientInfo.Patient_UID=Appointments.PatientFID WHERE Appointments.StartDateTime = (SELECT Max(Appointments.StartDateTime) FROM Appointments WHERE Appointments.PatientFID = PatientInfo.Patient_UID) ;