база данных сотрудников с изменяющимся окладом с течением времени - PullRequest
1 голос
/ 15 февраля 2010

У меня есть следующие таблицы:

PROJECTS - project_id, name
EMPLOYEES - employee_id, name
SALARY - employee_id, date, per_hour
HOURS - log_id, project_id, employee_id, date, num_hours

Мне нужно узнать, сколько стоит проект. Проблема в том, что зарплата может варьироваться. Например, человек может получить повышение.

В таблице SALARY регистрируется плата за человека в час. Каждое изменение стоимости записывается с указанием его даты.

Как я могу запросить эту информацию, чтобы убедиться, что журнал из таблицы HOURS всегда соответствует правильной записи из таблицы SALARY. Правильное совпадение: .. в зависимости от даты журнала часов, получите строку из таблицы зарплат с самой высокой датой перед датой журнала.

т. Е. Если работа была выполнена 14 февраля. Получить строку для этого сотрудника из таблицы зарплат с наивысшей датой ... но до 14-го числа.

Спасибо,

Ответы [ 3 ]

2 голосов
/ 15 февраля 2010

Вам нужна дата окончания SALARY. Когда в SALARY для сотрудника вставляется новая запись, в предыдущей записи с самой высокой датой (или, что еще лучше, с текущим флагом, установленным на «Y» в соответствии с рекомендациями cletus), в столбце конечной даты должна быть установлена ​​та же дата, что и для дата начала новой записи.

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

SELECT
  SUM(h.num_hours * s.per_hour) AS cost
FROM PROJECTS p
INNER JOIN HOURS h
  ON p.project_id = h.project_id
INNER JOIN (
    SELECT
      s1.employee_id,
      s1.date AS start_date,
      MIN(s2.date) AS end_date
    FROM SALARY s1
    INNER JOIN SALARY s2
      ON s1.employee_id = s2.employee_id
      AND s1.date < s2.date
    GROUP BY
      s1.employee_id,
      s1.date) s
  ON h.employee_id = s.employee_id
  AND h.date >= s.start_date
  AND h.date < s.end_date
0 голосов
/ 15 февраля 2010

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

Тогда ваше соединение довольно простое:

select h.num_hours, s.per_hour
from hours h
inner join salary s on h.employee_id = s.employee_id 
    and h.date >= s.StartDate and (h.date <= s.EndDate or s.EndDate is null)
0 голосов
/ 15 февраля 2010

В таблице «Часы» на самом деле введите значение заработной платы, которую вы используете (не связывайте ее на основе идентификатора). Это даст вам больше гибкости в будущем.

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