我的表格包含ID
(workers_id),Name
,time_worked
,time_to_work
,Contract_Start_Date
,Date_of_Entry
。此表包含工人每天的条目。我想计算他到目前为止收集的加班费。对于每个合同中的每个合同,我每个合同都有相同的条目,其中条目之间的唯一区别是Contract_STart_Date
和time_to_work
。一旦他得到一份新合同,他就会在那张桌子上每天得到一个新的entrie(我必须纠正那一天,但没有时间,所以认为这个问题不灵活)。
我有下表
| 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 |
我想把杰克的加班加起来作为相关合同。
我想我找到了解决这个问题的方法(逻辑上),但无法将我的想法转化为代码。这是方法:
我按合约每天设定一个数字(SeqNumber
)
(已经通过我的代码完成了。)
| 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
现在设置一个数字(ConSeqNumber
),date_of_entry属于contract_start_date
| 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
解决方案是对SeqNumber和ConSeqNumber相等的每个条目求和。
我的输出将是(根据计算time_worked
- time_to_work
并汇总值。
(8-8)+(8-8)+(6-4)+(8-4)= 6
| Overtime |
| -------- |
| 6 |
我的完整代码是:
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
答案 0 :(得分:0)
我还不太清楚你想要什么,所以我在下面为你提供了一些不同的选择。如果您发布所需的结果集,我们可以确保我们的解决方案符合您的要求。
DECLARE @Hours TABLE
(
WorkerID int,
WorkerName varchar(50),
TimeWorked int,
TimeToWork int,
ContractStartDate datetime,
DateOfEntry datetime
)
INSERT INTO @Hours (WorkerID, WorkerName, TimeWorked, TimeToWork, ContractStartDate, DateOfEntry) VALUES (11, 'Jack', 8, 8, '2013-01-01', '2013-01-01');
INSERT INTO @Hours (WorkerID, WorkerName, TimeWorked, TimeToWork, ContractStartDate, DateOfEntry) VALUES (11, 'Jack', 8, 8, '2013-01-01', '2013-01-02');
INSERT INTO @Hours (WorkerID, WorkerName, TimeWorked, TimeToWork, ContractStartDate, DateOfEntry) VALUES (12, 'Norman', 7, 6, '2013-01-01', '2013-01-01');
INSERT INTO @Hours (WorkerID, WorkerName, TimeWorked, TimeToWork, ContractStartDate, DateOfEntry) VALUES (11, 'Jack', 6, 4, '2013-04-15', '2013-04-15');
INSERT INTO @Hours (WorkerID, WorkerName, TimeWorked, TimeToWork, ContractStartDate, DateOfEntry) VALUES (11, 'Jack', 7, 8, '2013-01-01', '2013-04-15');
INSERT INTO @Hours (WorkerID, WorkerName, TimeWorked, TimeToWork, ContractStartDate, DateOfEntry) VALUES (11, 'Jack', 8, 4, '2013-04-15', '2013-04-16');
INSERT INTO @Hours (WorkerID, WorkerName, TimeWorked, TimeToWork, ContractStartDate, DateOfEntry) VALUES (11, 'Jack', 4, 8, '2013-01-01', '2013-04-16');
-- If you want the total for the worker for the full contract period repeated for each line, you could use this PARTITION BY version:
SELECT
*,
SUM(TimeWorked-TimeToWork) OVER (PARTITION BY WorkerID, ContractStartDate) AS OverTimeForContract,
-- if you don't want "undertime" to count against overtime, such that working 1 hour less one day doesn't absolve you from having worked 1 hour extra the previous day, you can do this fancy footwork:
SUM(CASE WHEN TimeWorked > TimeToWork THEN TimeWorked-TimeToWork ELSE 0 END) OVER (PARTITION BY WorkerID, ContractStartDate) AS OverTimeOnlyForContract
FROM @Hours
WHERE DateOfEntry BETWEEN '2013-01-01' AND '2013-04-15'; -- choose whatever dates you want, of course
-- If you don't need the value repeated for each entry, you could of course do a simple GROUP BY
SELECT
WorkerID,
WorkerName,
ContractStartDate,
SUM(TimeWorked-TimeToWork) AS OverTimeForContract,
SUM(CASE WHEN TimeWorked > TimeToWork THEN TimeWorked-TimeToWork ELSE 0 END) AS OverTimeOnlyForContract
FROM @Hours
WHERE DateOfEntry BETWEEN '2013-01-01' AND '2013-04-15'
GROUP BY WorkerID,
WorkerName,
ContractStartDate;
答案 1 :(得分:0)
我采用了@ Riley的相同数据样本。如果我拿走你的样本数据,那么加班也是正确的,即6。
;with CTE as
(
select *,ROW_NUMBER() over (partition by workerid,DateofEntry order by ContractStartDate asc) as seqnum,
ROW_NUMBER() over (partition by workerid order by workerid asc) as seqnum1
from @Hours
)
,CTE1 as
(
select WorkerID,sum(timeworked - timetowork)overtime from cte where seqnum=1 group by WorkerID
)
select a.WorkerID,a.WorkerName,b.overtime from cte a inner join cte1 b on a.WorkerID=b.WorkerID
where a.seqnum1=1
答案 2 :(得分:0)
以下方法获取最新合同的条目(通过检查没有其他条目具有较新的合同开始日期),然后查找time_worked和time_to_work之间的差异。
select
ID, Name, SUM(time_worked - time_to_work) as overtime, MAX(Contract_Start_Date) AS Contract_Start_Date
from
TimeEntry T1
WHERE
NOT EXISTS
(
SELECT 1
FROM
TimeEntry T2
WHERE T2.ID = T1.ID
AND T2.Date_of_Entry = T1.Date_of_Entry
AND T2.Contract_Start_Date > T1.Contract_Start_Date
)
GROUP BY ID, Name;
我很快就会创建一个SQL小提琴。
答案 3 :(得分:0)
好的,看起来我找到了解决方案:
数据样本
CREATE TABLE #test(WorkerID int,
TimeWorked int,
TimeToWork int,
ContractStartDate datetime,
DateOfEntry datetime
INSERT INTO #test (WorkerID, TimeWorked, TimeToWork, ContractStartDate, DateOfEntry) VALUES (11, 8, 8, '2013-01-01', '2013-01-01');
INSERT INTO #test (WorkerID, TimeWorked, TimeToWork, ContractStartDate, DateOfEntry) VALUES (11, 8, 4, '2013-04-15', '2013-01-01');
INSERT INTO #test (WorkerID, TimeWorked, TimeToWork, ContractStartDate, DateOfEntry) VALUES (11, 8, 6, '2013-08-15', '2013-01-01');
INSERT INTO #test (WorkerID, TimeWorked, TimeToWork, ContractStartDate, DateOfEntry) VALUES (11, 8, 8, '2013-01-01', '2013-01-02');
INSERT INTO #test (WorkerID, TimeWorked, TimeToWork, ContractStartDate, DateOfEntry) VALUES (11, 8, 4, '2013-04-15', '2013-01-02');
INSERT INTO #test (WorkerID, TimeWorked, TimeToWork, ContractStartDate, DateOfEntry) VALUES (11, 8, 6, '2013-08-15', '2013-01-02');
INSERT INTO #test (WorkerID, TimeWorked, TimeToWork, ContractStartDate, DateOfEntry) VALUES (11, 7, 8, '2013-01-01', '2013-04-15');
INSERT INTO #test (WorkerID, TimeWorked, TimeToWork, ContractStartDate, DateOfEntry) VALUES (11, 6, 4, '2013-04-15', '2013-04-15');
INSERT INTO #test (WorkerID, TimeWorked, TimeToWork, ContractStartDate, DateOfEntry) VALUES (11, 6, 6, '2013-08-15', '2013-04-15');
INSERT INTO #test (WorkerID, TimeWorked, TimeToWork, ContractStartDate, DateOfEntry) VALUES (11, 4, 8, '2013-01-01', '2013-04-16');
INSERT INTO #test (WorkerID, TimeWorked, TimeToWork, ContractStartDate, DateOfEntry) VALUES (11, 8, 4, '2013-04-15', '2013-04-16');
INSERT INTO #test (WorkerID, TimeWorked, TimeToWork, ContractStartDate, DateOfEntry) VALUES (11, 4, 6, '2013-08-15', '2013-04-16');
INSERT INTO #test (WorkerID, TimeWorked, TimeToWork, ContractStartDate, DateOfEntry) VALUES (11, 2, 8, '2013-01-01', '2013-08-16');
INSERT INTO #test (WorkerID, TimeWorked, TimeToWork, ContractStartDate, DateOfEntry) VALUES (11, 2, 6, '2013-04-15', '2013-08-16');
INSERT INTO #test (WorkerID, TimeWorked, TimeToWork, ContractStartDate, DateOfEntry) VALUES (11, 2, 5, '2013-08-15', '2013-08-16');
并且我得到了我想要的东西。非常感谢大家的帮助!
---select WorkerID,(sum(TimeWorked)-sum(TimeToWork)) as 'overtime'
select * ---sum(timeworked - timetowork)
from (
Select *,
ROW_NUMBER() over (partition by DateOfEntry order by ContractStartDate desc) as seqnum
from #test
where ContractStartDate <= DateOfEntry)
#test
where seqnum = 1
drop table #test