Рекомендации по проектированию базы данных / SQL для извлечения данных в хронологическом порядке - PullRequest
4 голосов
/ 14 марта 2010

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

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

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

  • (а) Дата последнего посещения
  • (b) Прогнозируемая будущая дата посещения (т.е. последняя дата посещения + 1 календарный год)

С точки зрения моей базы данных, любой данный сотрудник может иметь несколько дат посещения курсов в прошлом:

EmpName          AttandanceDate

Joe Bloggs             1st Jan 2007
Joe Bloggs           4th Jan 2008
Joe Bloggs           3rd Jan 2009
Joe Bloggs           8th Jan 2010

Мой вопрос: каков наилучший способ настроить базу данных, чтобы упростить получение самой последней даты посещения курса? В приведенном выше примере самым последним будет 8 января 2010 года.

Есть ли хороший способ использовать SQL для сортировки по дате и выбора МАКСИМАЛЬНОЙ даты?

Моя другая идея состояла в том, чтобы добавить столбец с именем «MostRecent» и просто установить для него значение ИСТИНА.

EmpName    AttandanceDate         MostRecent
Joe Bloggs  1st Jan 2007           False
Joe Bloggs  4th Jan 2008           False
Joe Bloggs  3rd Jan 2009           False
Joe Bloggs  8th Jan 2010           True

Я задавался вопросом, упростит ли это SQL, т.е.

SELECT Joe Bloggs WHERE MostRecent = ‘TRUE’

Кроме того, когда пользователь обновляет запись о посещаемости данного сотрудника (т. Е. С последней датой посещаемости), я мог использовать SQL для:

  1. Поиск сотрудника и установка MostRecent значение в FALSE
  2. Добавить новую запись с MostRecent, установленной в TRUE?

Кто-нибудь порекомендовал бы один метод по сравнению с другим? Или у вас есть совершенно другой способ решения этой проблемы?

Ответы [ 4 ]

3 голосов
/ 14 марта 2010

Чтобы получить дату последнего посещения, используйте групповую функцию MAX, т.е.

SELECT MAX(AttandanceDate)  
FROM   course_data
WHERE  employee_name = 'Joe Bloggs'

Чтобы получить максимальную дату посещения для всех сотрудников:

SELECT   employee_name, MAX(AttandanceDate)  
FROM     course_data
GROUP BY employee_name
ORDER BY employee_name

Запрос выше НЕ вернет данные для сотрудников, которые не посещали никаких курсов. Поэтому вам нужно выполнить другой запрос.

SELECT   A.employee_name, B.AttandanceDate
FROM     employee AS A
LEFT JOIN (
           SELECT   employee_id, MAX(AttandanceDate) AS AttandanceDate
           FROM     course_data
           GROUP BY employee_id
          ) AS B ON A.id = B.employee_id
ORDER BY A.employee_name

Для сотрудников, которые не посещали какие-либо курсы, запрос вернет NULL AttendanceDate.

0 голосов
/ 14 марта 2010

Если вы используете SQL Server 2005 или 2008 или более позднюю версию, вы можете использовать row_number() сделать что-то вроде следующего. Это будет список всех, с их самой последней посещаемостью.

with temp1 as 
 (select *
      , (row_number() over (partition by EmpName order by AttandanceDate descending)) 
        as [CourseAttendanceOrder]
    from AttendanceHistory)
select *
  from temp
 where CourseAttendanceOrder = 1
 order by EmpName

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

Однако, если вы всегда будете фокусироваться на одном человеке за раз, может быть более эффективно создать хранимую процедуру, которая может использовать операторы типа select max(AttandanceDate) только для человека, с которым вы работаете.

0 голосов
/ 14 марта 2010

Это может уже иметь место, но вывод из столбцов AttandanceDate заставляет меня подозревать, что этот столбец может не быть столбцом datetime. Большинство СУБД имеют какие-то типы данных даты, времени и / или даты и времени, которые используются для хранения этой информации. В котором ответы Кандада Боггу и OMG Ponies идеальны. Но если вы храните свои даты в виде строк, у вас БУДУТ проблемы с попытками сделать любое из их предложений.

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

например. SELECT YEAR (2008-01-01) вернет 2008 как целое число.

0 голосов
/ 14 марта 2010

Флаг является избыточным. Другой способ, как получить последний рабочий день сотрудника:

select top 1 AttandanceDate
from course_data
WHERE  employee_name = 'Joe Bloggs'
order by AttandanceDate desc
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...