2012-04-17 67 views
8

SQL新手在這裏有效的成本率。我試圖生成一個成本計算查詢,輸出員工時間卡信息並根據有效的員工成本計算比率計算成本。SQL查詢,選擇基於電荷日期

我的問題是一個類似於這裏問:Retro-active effective date changes with overlapping dates但我不處理的復古活動或重疊的日期範圍。

表的例子(在費率表的空值指示當前速率):

CREATE TABLE Emp_Rate 
(
    Emp int, 
    Rate money, 
    Rate_Start datetime, 
    Rate_Exp datetime 
) 

CREATE TABLE Emp_Time 
(
    Emp int, 
    Chrg_Date datetime, 
    Chrg_Code varchar(10), 
    Chrg_Hrs decimal(8, 2) 
) 

Insert into Emp_Rate (Emp,Rate,Rate_Start,Rate_Exp) Values ('1','20','5/1/09','4/30/10') 
Insert into Emp_Rate (Emp,Rate,Rate_Start,Rate_Exp) Values ('1','21','5/1/10','4/30/11') 
Insert into Emp_Rate (Emp,Rate,Rate_Start,Rate_Exp) Values ('1','22','5/1/11',NULL) 

Insert into Emp_Time (Emp,Chrg_Date,Chrg_Code,Chrg_Hrs) Values ('1','5/10/09','B','8') 
Insert into Emp_Time (Emp,Chrg_Date,Chrg_Code,Chrg_Hrs) Values ('1','5/10/10','B','8') 
Insert into Emp_Time (Emp,Chrg_Date,Chrg_Code,Chrg_Hrs) Values ('1','5/10/11','B','8') 

查詢(返回愚弄由多個速率條目(顯然引起)):

Select Emp_Time.Emp, 
     Cast(Emp_Time.Chrg_Date as DATE) as 'Chrg_Date', 
     Emp_Time.Chrg_Code, 
     Emp_Time.Chrg_Hrs, 
     Emp_Rate.Rate, 
     Emp_Time.Chrg_Hrs * Emp_Rate.Rate as 'Cost' 

From Emp_Time inner join 
     Emp_Rate on Emp_Rate.Emp = Emp_Time.Emp 

Order By [Emp],[Chrg_Date] 

所需的輸出:

Emp Chrg_Date Chrg_Code Chrg_Hrs Rate Cost 
1 2009-05-10 B   8.00  20.00 160.00 
1 2010-05-10 B   8.00  21.00 168.00 
1 2011-05-10 B   8.00  22.00 176.00 

我已經繞圈使用Between運算符在子查詢中根據收費日期隔離正確的費率,但沒有任何運氣。

我感謝任何幫助!

+0

+1了詳細具體的問題。您期望的輸出顯示Emp 2,但您的插入是Emp 1。是否是錯字? – Taryn 2012-04-17 18:23:14

+0

是的,它是錯字!我最初的例子有兩名員工。糾正。 – Jaxaeon 2012-04-17 18:26:50

+0

用您的數據庫類型標記您的問題。 MySQL的? – barsju 2012-04-17 18:39:47

回答

2

沒有指定的DBMS鍵入下面的答案是SQL服務器。我相信還有其他方法可以做到這一點,但這種方式將取代nullRate_Exp日期與當前日期。

Select et.Emp, 
     Cast(et.Chrg_Date as DATEtime) as 'Chrg_Date', 
     et.Chrg_Code, 
     et.Chrg_Hrs, 
     er.Rate, 
     et.Chrg_Hrs * er.Rate as 'Cost' 
From Emp_Time et 
inner join 
(
    SELECT Emp 
     , Rate 
     , Rate_Start 
     , CASE 
      WHEN Rate_Exp is Null 
      THEN Convert(varchar(10), getdate(), 101) 
      ELSE Rate_Exp 
      END as Rate_Exp 
    FROM Emp_Rate 
)er 
    on er.Emp = et.Emp 
WHERE (et.Chrg_Date BETWEEN er.Rate_Start AND er.Rate_Exp) 
Order By et.Emp,et.Chrg_Date 

或使用CASE聲明在WHERE條款:

Select et.Emp, 
     Cast(et.Chrg_Date as DATEtime) as 'Chrg_Date', 
     et.Chrg_Code, 
     et.Chrg_Hrs, 
     er.Rate, 
     et.Chrg_Hrs * er.Rate as 'Cost' 
From Emp_Time et 
inner join Emp_Rate er 
    on er.Emp = et.Emp 
WHERE (et.Chrg_Date 
     BETWEEN er.Rate_Start 
       AND CASE WHEN er.Rate_Exp Is Null 
      THEN Convert(varchar(10), getdate(), 101) 
      ELSE er.Rate_Exp END) 
+0

這看起來不錯!我必須將它修補成一個查詢,並且有更多的連接應該很有趣。謝謝你給我幾個選擇! – Jaxaeon 2012-04-17 19:07:07

+0

肯定的事情,很高興幫助。 – Taryn 2012-04-17 19:08:52

+0

實施和工作像一個魅力。當選爲使用第二種解決方案的優雅。 – Jaxaeon 2012-04-17 20:17:16