2010-02-15 32 views
1

我有以下表格:員工數據庫隨着時間的推移

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表記錄員工的per_hour費用。隨着日期的變化記錄每次成本變化。

如何查詢此信息以確保HOURS表中的日誌始終與SALARY表中的正確條目相匹配。右匹配是..取決於小時日誌的日期,從日誌日期之前的最高日期的工資表中獲取行。

即如果工作在2月14日進行。從最高日期的工資表中獲取此員工的行...但仍在14日之前。

謝謝

回答

2

你需要的是薪水的結束日期。當一條新記錄插入到員工的SALARY中時,具有最高日期的上一條記錄(或更好的是,當前標誌由cletus建議設置爲'Y')應該將其結束日期列設置爲與新紀錄的開始日期。

這應該適用於您當前的模式,但請注意它可能會很慢。

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

在「營業時間」表實際登錄您使用(基於ID不鏈接吧)工資的價值。這將給你未來更大的靈活性。

0

我已經找到了處理跨越日期這​​樣的查詢最簡單的方法就是存儲StartDateEndDate,其中EndDateNULL當前薪水。我使用觸發器確保EndDate的值只有一個NULL,並且沒有重疊的日期範圍或範圍之間的間隔。 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

@cletus正確性比可伸縮性更重要 –

+0

@cletus這是一個工資系統,這意味着它計算出多少人付錢。這是他們生活的金錢。我懷疑正確性是相當重要的,並且任何一家公司在工資單上都存在可擴展性問題,將能夠負擔硬件來正確處理工資。這是一個遊戲或Facebook或類似的,當然,權衡會有所不同。 –

+0

@cletus:*「過早優化是萬惡之源」*是另一個口頭禪;你正在重申這個問題是關於性能問題,而不是提供問題的解決方案,這就是如何查詢歷史薪水。 – RedFilter

相關問題