2010-12-27 7 views
1

Ich habe eine Situation, in der ich einer Angestelltenzeitkarte einen passenden Rate zuweisen muss. Der Angestellte wird seine Zeit unabhängig von einer Rate aufzeichnen (d. H. Es ist nicht verfügbar, wenn die Zeit aufgezeichnet wird). Das System, in dem die Tarife gespeichert sind, erhält tägliche Aktualisierungen, und die Preise können zu jedem Zeitpunkt innerhalb der Kalkulationsperiode zurückdatiert werden (rückwirkend). Zu Berichtszwecken muss ich die Rate an bestimmten Tagen melden können. Betrachten Sie die folgenden Tabellen:Rückwirkendes effektives Datum ändert sich mit überlappenden Daten

create table #timesheet (
    txid int identity(1,1) 
    , empid int 
    , work_date datetime 
    , jobno varchar(16) 
    , hoursamt decimal(8,2) 
) 

create table #payrate (
    txid int identity(1,1) 
    , empid int 
    , rate money 
    , eff_date datetime 
    , asof_date datetime 
) 

insert into #timesheet (empid, work_date, jobno, hoursamt) values (1, '2010-01-01', 'A', 8) 
insert into #timesheet (empid, work_date, jobno, hoursamt) values (1, '2010-01-02', 'A', 8) 
insert into #timesheet (empid, work_date, jobno, hoursamt) values (1, '2010-01-03', 'A', 8) 
insert into #timesheet (empid, work_date, jobno, hoursamt) values (1, '2010-01-04', 'A', 8) 
insert into #timesheet (empid, work_date, jobno, hoursamt) values (2, '2010-01-01', 'B', 8) 
insert into #timesheet (empid, work_date, jobno, hoursamt) values (2, '2010-01-02', 'B', 8) 
insert into #timesheet (empid, work_date, jobno, hoursamt) values (2, '2010-01-03', 'B', 8) 
insert into #timesheet (empid, work_date, jobno, hoursamt) values (2, '2010-01-04', 'B', 8) 

insert into #payrate (empid, rate, eff_date, asof_date) values (1, 10, '2010-01-01', '2010-01-01')  -- Starting rate 
insert into #payrate (empid, rate, eff_date, asof_date) values (1, 11, '2010-01-03', '2010-01-05')  -- Retro active 
insert into #payrate (empid, rate, eff_date, asof_date) values (2, 8, '2010-01-01', '2010-01-01')  -- Starting rate 
insert into #payrate (empid, rate, eff_date, asof_date) values (2, 9, '2010-01-03', '2010-01-02')  -- Retro active date 
insert into #payrate (empid, rate, eff_date, asof_date) values (2, 10, '2010-01-01', '2010-01-05')  -- Retro active date 

Ich würde eine Abfrage wie die einen Parameter (die asof_date) akzeptiert, die das Datum angibt, die Preise wirksam waren. Die gleiche Abfrage würde die folgenden Ergebnisse für die folgenden 'asof' Daten zurückgeben. Beachten Sie, dass rückwirkende Änderungen am Fälligkeitsdatum in der Zahlungstabelle wirksam werden. Angenommen, die Sätze sind gültig, bis sie über einen Eintrag in der Zahlungstabelle geändert werden. Kosten = Rate * Stunden. Die Daten sind im Format JJJJ-MM-TT. Die Notizen dienen nur als Referenz und sollten nicht in der Ergebnismenge zurückgegeben werden.

declare @asof datetime 
set @asof = '2010-01-01' 

---------------------------------------------------- 
empid | work_date | jobno | hoursamt | rate | cost | Notes 
---------------------------------------------------- 
1  2010-01-01 A  8   10  80  Rate effective the 1st 
1  2010-01-02 A  8   10  80 
1  2010-01-03 A  8   10  80 
1  2010-01-04 A  8   10  80 
2  2010-01-01 B  8   8  64  Rate effective the 1st 
2  2010-01-02 B  8   8  64 
2  2010-01-03 B  8   8  64 
2  2010-01-04 B  8   8  64 



declare @asof datetime 
set @asof = '2010-01-03' 

---------------------------------------------------- 
empid | work_date | jobno | hoursamt | rate | cost | Notes 
---------------------------------------------------- 
1  2010-01-01 A  8   10  80  Rate effective the 1st 
1  2010-01-02 A  8   10  80 
1  2010-01-03 A  8   10  80 
1  2010-01-04 A  8   10  80 
2  2010-01-01 B  8   8  64  
2  2010-01-02 B  8   8  64 
2  2010-01-03 B  8   9  72  Rate effective the 3rd 
2  2010-01-04 B  8   9  72 


declare @asof datetime 
set @asof = '2010-01-06' 

---------------------------------------------------- 
empid | work_date | jobno | hoursamt | rate | cost | Notes 
---------------------------------------------------- 
1  2010-01-01 A  8   10  80  
1  2010-01-02 A  8   10  80 
1  2010-01-03 A  8   11  88  Rate effective the 3rd 
1  2010-01-04 A  8   11  88 
2  2010-01-01 B  8   10  80  Rate effective the 1st 
2  2010-01-02 B  8   10  80 
2  2010-01-03 B  8   10  80 
2  2010-01-04 B  8   10  80 

Vielen Dank im Voraus!

+0

declare @maxdate Datumzeit, @asof Datumzeit Satz @asof '2010-01-06' = Satz @maxdate = '2199.01.01' wählen t.empid, t.work_date, t. jobno, t.hoursamt, r.rate, t.hoursamt * r.rate Kosten von #timesheet t innere Verknüpfung ( \t wählen empid \t \t, Rate \t \t, eff_date als eff_from \t \t, (select isnull (min (b.eff_date), @maxdate) als eff_von \t \t \t von #payrate b \t \t \t wo b.empid = a.empid \t \t \t und b.eff_date> a.eff_date \t \t \t \t und b.asof_date <@asof \t \t) als eff_thru \t von #payrate a \t wo asof_date <= @asof ) als auf r = t.empid r.empid und (t.work_date zwischen r.eff_from und r.eff_thru) –

+0

verwendete ich den obigen Code aber es gibt Duplikate zurück. –

Antwort

1

Sie können outer apply verwenden, um nach einer bestimmten Zahlung zu suchen. In diesem Beispiel wird eine outer apply mit einer top 1 kombiniert, um die letzte Payrate auszuwählen.

select t.empid 
,  t.work_date 
,  t.jobno 
,  t.hoursamt 
,  rate.rate 
,  t.hoursamt * rate.rate 
from #timesheet t 
outer apply 
     (
     select top 1 * 
     from #payrate p 
     where p.empid = t.empid 
       and p.asof_date <= @asof 
       and p.eff_date <= t.work_date 
     order by 
       p.eff_date desc 
     ) rate 
+0

Das funktioniert perfekt. Vielen Dank! –

Verwandte Themen