I have a Table with ID
(workers_id), Name
, time_worked
, time_to_work
, Contract_Start_Date
, Date_of_Entry
. This table holds the entries for every day for a worker. I want to calculate the overtime he collected up till now. I have the same entry for each contract in that table for every day where the only difference between the entries is the Contract_STart_Date
and the time_to_work
. As soon as he gets a new contract he gets a new entrie for every day in that table (I have to correct that one day but have no time atm, so take that as unflexible for that problem).
I have the following table
| ID | Name | time_worked | time_to_work | Contract_Start_Date | Date_of_Entry |
| -- | ---- | ----------- | ------------ | ------------------- | ------------- |
| 11 | Jack | 8 | 8 | 2013-01-01 | 2013-01-01 |
| 11 | Jack | 8 | 8 | 2013-04-01 | 2013-01-01 |
| 11 | Jack | 8 | 8 | 2013-01-01 | 2013-01-02 |
| 11 | Jack | 8 | 8 | 2013-04-01 | 2013-01-02 |
...
| 11 | Jack | 6 | 8 | 2013-01-01 | 2013-04-15 |
| 11 | Jack | 6 | 4 | 2013-04-15 | 2013-04-15 |
| 11 | Jack | 8 | 8 | 2013-01-01 | 2013-04-16 |
| 11 | Jack | 8 | 4 | 2013-04-15 | 2013-04-16 |
I want to add up the overtime for Jack for the relevant contract.
I think I found a way to solve this (logically) but cannot transfer my thoughts into code. This is the approach:
I set a number (SeqNumber
) for each day by contract
(already accomplished by my code below).
| ID | Name | time_worked | time_to_work | Contract_Start_Date | Date_of_Entry | SeqNumber
| -- | ---- | ----------- | ------------ | ------------------- | ------------- |----------
| 11 | Jack | 8 | 8 | 2013-01-01 | 2013-01-01 |1
| 11 | Jack | 8 | 8 | 2013-04-01 | 2013-01-01 |2
| 11 | Jack | 8 | 8 | 2013-01-01 | 2013-01-02 |1
| 11 | Jack | 8 | 8 | 2013-04-01 | 2013-01-02 |2
...
| 11 | Jack | 6 | 8 | 2013-01-01 | 2013-04-15 |1
| 11 | Jack | 6 | 4 | 2013-04-15 | 2013-04-15 |2
| 11 | Jack | 8 | 8 | 2013-01-01 | 2013-04-16 |1
| 11 | Jack | 8 | 4 | 2013-04-15 | 2013-04-16 |2
now is set a number (ConSeqNumber
) to which contract_start_date the date_of_entry belongs
| ID | Name | time_worked | time_to_work | Contract_Start_Date | Date_of_Entry | SeqNumber| ConSeqNumber
| -- | ---- | ----------- | ------------ | ------------------- | ------------- |----------| ------------
| 11 | Jack | 8 | 8 | 2013-01-01 | 2013-01-01 |1 |1
| 11 | Jack | 8 | 8 | 2013-04-01 | 2013-01-01 |2 |1
| 11 | Jack | 8 | 8 | 2013-01-01 | 2013-01-02 |1 |1
| 11 | Jack | 8 | 8 | 2013-04-01 | 2013-01-02 |2 |1
...
| 11 | Jack | 6 | 8 | 2013-01-01 | 2013-04-15 |1 |2
| 11 | Jack | 6 | 4 | 2013-04-15 | 2013-04-15 |2 |2
| 11 | Jack | 8 | 8 | 2013-01-01 | 2013-04-16 |1 |2
| 11 | Jack | 8 | 4 | 2013-04-15 | 2013-04-16 |2 |2
The solution would be to sum every entry where the SeqNumber and the ConSeqNumber are equal.
My output would be (according to the calculation time_worked
- time_to_work
and summarize the values.
(8-8) + (8-8) + (6-4) + (8-4) = 6
| Overtime |
| -------- |
| 6 |
My full code is:
select ID, Name,(sum(time_worked)-sum(time_to_work)) as 'overtime'
from (
Select *,
ROW_NUMBER() over (partition by Date_of_Entry order by Contract_Start_Date asc) as seqnum
from MyTable where Contract_Start_Date <= Date_of_Entry
)
MyTable
WHERE seqnum = 1
AND YearA = DATEPART(YEAR, GETDATE()) -1
AND DATE_of_Entry <= GETDATE()
AND DATEPART(MONTH, Date_of_Entry) BETWEEN 4 and 9
GROUP BY ID, Name