2012-04-17 8 views
8

SQL初心者はここになります。私は従業員のタイムカード情報を出力し、有効な従業員の原価計算率に基づいてコストを計算する原価計算クエリを生成しようとしています。請求日に基づいて有効な原価計算レートを選択するSQLクエリ

私の質問は、ここに尋ねられた質問に似ています:Retro-active effective date changes with overlapping datesですが、私はレトロ活動や日付範囲の重複を扱っていません。

表の例(速度テーブルのNULL値は、現在のレートを示す):

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] 

所望の出力:

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') 

クエリー(複数レートエントリ(明らかに)によって引き起こさdupesを返します)。私はBetween演算子を使用して、円の中を行ってきた

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 

料金の日付に基づいて正しいレートを分離するためにサブクエリでは、しかし運がなかった。

ご協力いただきありがとうございます。

+0

+1を。あなたの希望する出力にはEmp 2が表示されますが、挿入物はEmp 1用です。これは誤植ですか? – Taryn

+0

はい、それはタイプミスでした!元の例には2人の従業員がいました。修正されました。 – Jaxaeon

+0

あなたの質問にあなたのデータベースタイプをタグ付けしてください。 MySQL? – barsju

答えて

2

DBMSのタイプを指定しなかったので、以下の答えはsql-serverです。私はこれを行う他の方法があると確信していますが、この方法は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 

たり、WHERE句でCASEステートメントを使用します。詳細な質問のため

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

+0

確かに、喜んで助けてください。 – Taryn

+0

実装され、魅力的に動作します。その優雅さのために第2のソリューションを使用することを選んだ。 – Jaxaeon

関連する問題