Запрос трех связанных таблиц, показывающих только самые последние записи для каждого человека, с SQL в MS Access - PullRequest
1 голос
/ 07 марта 2012

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

Регистранты

  • Идентификатор регистранта (первичный ключ)

Соответствия

  • Идентификатор корреспонденции

  • Время корреспонденции

  • Дата корреспонденции

  • ID регистранта (внешний ключ)

  • ID курса (внешний ключ)

курс

  • Идентификатор курса (первичный ключ)

Идея состоит в том, что мы можем записывать, кто зарегистрировался для какого курса, является ли курс полным и т. Д., Отслеживая при этомвсе изменения на этом пути и ведение подробных заметок для каждого телефонного звонка, электронной почты, факса и т. д. (есть намного больше полей, чем я показал здесь).

Мне нужен запрос с одним уникальнымИдентификатор владельца регистрации и идентификатор курса в последней записи о переписке (в соответствии с временем и датой переписки) в каждой строке.Таким образом, в основном я могу посмотреть на запрос и прочесть что-то вроде этого:

  • "Человек А последний сказал, что хотел бы посетить курс C в это время и дату"

  • «Человек D в последний раз сказала, что хотела бы посещать курс А в это время и дату»

Решения, использующие SQL или пользовательский интерфейс MS Access «Design View»оба в порядке.

Ответы [ 2 ]

2 голосов
/ 07 марта 2012

Это усложняется, потому что дата и время находятся в отдельных полях.

Если вы используете последовательный идентификатор Autonum в Access, вы можете использовать CorrespondenceID, чтобы указать самый последний.

Попробуйте что-то вроде этого:

SELECT 
  Reg.Name,
  Course.Name,
  C.CorrespondenceDate,
  C.CorrespondenceTime
FROM
  (SELECT MAX(CorrespondenceID) AS ID, RegistrantID, CourseID
     FROM Correspondence
      GROUP BY RegistrantID, CourseID) AS CX
  INNER JOIN Correspondences AS C ON CX.CorrespondenceID = CX.ID
  INNER JOIN Registrants Reg on CX.RegistrantID = Reg.RegistrantID
  INNER JOIN Course ON CX.CourseID = Course.CourseID;

Если вы не используете последовательную автономию, вам придется объединить поля даты и времени, чтобы определить, какая из них самая последняя. Вы, вероятно, могли бы заменить MAX(CorrespondenceDate + CorrespondenceTime) в подзапросе CX выше.

Пара других вещей, которые вы могли бы рассмотреть:

  • Используйте одно поле DateTime, а заполнение с помощью Now () облегчит определение последних.
  • У вас смешаны множественные числа в именах таблиц "курс" (единственное число) и "регистрант" (множественное число) - вы, вероятно, должны быть последовательны - многие люди предпочитают единственное число
  • Я хотел бы рассмотреть возможность регистрации в таблице, которая сопоставляет курс и регистранта, а затем сопоставить соответствие с регистрацией. Мне кажется, это лучше.
1 голос
/ 07 марта 2012

Вам нужно несколько скобок в MS Access.

SELECT c1.[correspondence id],
       r.[registrant id],
       c2.[course id],
       [correspondence date] + [correspondence time] AS expr1
FROM   course c2
       INNER JOIN (registrants r
                   INNER JOIN correspondences c1
                     ON r.[registrant id] = c1.[registrant id])
         ON c2.[course id] = c1.[course id]
WHERE  [correspondence id] IN (SELECT [correspondence id]
                               FROM   correspondences b
                               WHERE  b.[registrant id] = c1.[registrant id]
                                      AND [correspondence date] +
                                          [correspondence time]
                                          =
                                          (SELECT MAX([correspondence date] +
                                                      [correspondence time])
                                           FROM   correspondences
                                           WHERE
                                              [registrant id] =
                                              c1.[registrant id]))

Я бы очень быстро сошел с ума, если бы мне пришлось работать с этими таблицами.Избавьтесь от всех пробелов.

...