SQL - обновление записей на основе самой последней даты - PullRequest
3 голосов
/ 12 сентября 2009

У меня проблемы с обновлением записей в базе данных на основе самой последней даты, и я ищу некоторые рекомендации. Кстати, я новичок в SQL.

В качестве фона у меня есть приложение Windows Forms с SQL Express, и я использую ADO.NET для взаимодействия с базой данных. Приложение предназначено для того, чтобы пользователь мог отслеживать посещаемость сотрудниками различных курсов, которые необходимо посещать на регулярной основе (например, каждые 6 месяцев, каждый год и т. Д.). Например, они могут получить данные, чтобы увидеть, когда сотрудники последний раз посещали данный курс, а также обновить даты посещения, если сотрудник недавно прошел курс.

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

  1. EmployeeDetailsTable - простой список имен сотрудников, адреса электронной почты и т. Д., Каждый с уникальным идентификатором
  2. CourseDetailsTable - простой список курсов, каждый с уникальным идентификатором (например, 1, 2, 3 и т. Д.)
  3. AttendanceRecordsTable - имеет 3 столбца {EmployeeID, CourseID, AttendanceDate, Comments}

Для любого данного курса у сотрудника будет история посещений, т. Е. Если курс необходимо посещать каждый год, то у него будет одна запись за столько лет, сколько он провел в компании.

Что я хочу сделать, это обновить поле «Комментарии» для данного сотрудника и данного курса на основе самой последней даты посещения. Каков «правильный» синтаксис SQL для этого?

Я пробовал много вещей (как показано ниже), но не могу заставить его работать:

UPDATE AttendanceRecordsTable
SET Comments = @Comments
WHERE AttendanceRecordsTable.EmployeeID = (SELECT EmployeeDetailsTable.EmployeeID FROM EmployeeDetailsTable WHERE (EmployeeDetailsTable.LastName =@ParameterLastName AND EmployeeDetailsTable.FirstName =@ParameterFirstName)
AND AttendanceRecordsTable.CourseID = (SELECT CourseDetailsTable.CourseID FROM CourseDetailsTable WHERE CourseDetailsTable.CourseName =@CourseName))
GROUP BY MAX(AttendanceRecordsTable.LastDate)

После долгих поисков я обнаружил, что MAX является агрегатной функцией, и поэтому мне нужно использовать GROUP BY. Я также пытался использовать ключевое слово HAVING, но безуспешно.

Кто-нибудь может указать мне правильное направление? Каков «обычный» синтаксис для обновления записи в базе данных на основе самой последней даты?

Ответы [ 2 ]

6 голосов
/ 12 сентября 2009

То есть вы хотите обновить AttendantsRecordsTable и установить комментарий к комментарию в самом последнем CourseDetailsTable для каждого сотрудника?

UPDATE 
  dbo.AttendanceRecordsTable
SET 
  Comments = @Comments
FROM
  CourseDetailsTable cd 
INNER JOIN
  Employee e ON e.EmployeeID = AttendanceRecordTable.EmployeeID
WHERE 
  e.LastName = @LastName 
  AND e.FirstName = @FirstName
  AND cd.CourseName = @CourseName
  AND AttendanceRecordsTable.CourseID = cd.CourseID
  AND AttendanceRecordsTable.LastDate = 
        (SELECT MAX(LastDate) 
           FROM AttendanceRecordsTable a
          WHERE a.EmployeeID = e.EmployeeID 
            AND a.CourseID = cd.CourseID)

Я думаю, что-то подобное должно работать.

В основном вам необходимо выполнить соединение между таблицей AttendanceRecordTable, которую вы хотите обновить, и таблицами Employee и CourseDetailsTable. Для этих двух вы определили определенные параметры для выбора каждой отдельной строки, а затем вам нужно убедиться, что вы обновляете только последнюю запись AttendanceRecordTable, которую вы делаете, убедившись, что это MAX (LastDate) таблицы. *

Подвыбрать здесь:

(SELECT MAX(LastDate) 
   FROM AttendanceRecordsTable a
  WHERE a.EmployeeID = e.EmployeeID AND a.CourseID = cd.CourseID)

выберет МАКС (последний) из LastDate записей в AttendanceRecordsTable, основываясь на выборе данного сотрудника (e.EmployeeID) и данного курса (cd.CourseID).

Соедините это с выбором, чтобы выбрать одного сотрудника по имени и фамилии (это, конечно, работает, только если у вас никогда нет двух John Miller в вашей таблице сотрудников!). Вы также выбираете курс с помощью названия курса, так что оно также должно быть уникальным - в противном случае вы получите несколько совпадений в таблице курсов.

Марк

0 голосов
/ 12 сентября 2009

Предполагая, что первичный ключ на AttendanceRecordsTable равен id:

UPDATE AttendanceRecordsTable SET Comments = @Comments
WHERE AttendanceRecordsTable.id = (
    SELECT AttendanceRecordsTable.id
        FROM EmployeeDetailsTable 
        JOIN AttendanceRecordsTable ON AttendanceRecordsTable.EmployeeID = EmployeeDetailsTable.EmployeeID·
        JOIN CourseDetailsTable ON AttendanceRecordsTable.CourseID = CourseDetailsTable.CourseID
    WHERE
        EmployeeDetailsTable.LastName =@ParameterLastName AND EmployeeDetailsTable.FirstName =@ParameterFirstName AND
        CourseDetailsTable.CourseName =@CourseName
    ORDER BY AttendanceRecordsTable.LastDate DESC LIMIT 1)

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

Редактировать: я просто прочитал ваше сообщение еще раз, у вас нет ни одного столбца первичного ключа на AttendanceRecordsTable. Облом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...