June 20, 2006 at 5:04 am
Hallo, so i have test it in all ways. Its look great. The only Problem is the time 01.01.05 til 21.09.05 its the Format i have written.loginzeit and logoutzeit looks like that
'1900-01-01 22:00:00' and not '1899-12-30 and 22:00:00'..
Please what can i do to change it.
Greetings Thomas
June 20, 2006 at 6:30 am
See Last Post!
N 56°04'39.16"
E 12°55'05.25"
June 20, 2006 at 6:47 am
Hallo,
i have done it and now there are no counts or Time in the Column 22-24 ? I dont Knowh why there are different standards. It every night update from an txt file with an bulkinsert task.
My head it knocking. Its look like the best i have seen what do you programming.
Thomas
June 20, 2006 at 7:50 am
Hallo,
i have found the misterium .
its the Timestamp '22:00:00.000', '23:59:59.999'.
I write this '22:00:00.000', '23:59:59' and then they count and sum.Do you think its ok??Or change this writing anything ??
Thanks
Thomas
June 20, 2006 at 8:12 am
No, it will not change the fact that you sometimes have time with '1899-12-30' (ms access standard) and sometimes time with '1900-01-01' (ms sql server standard).
The problem arises when adding together LoginDate and LoginZeit, or LogoutDate and LogoutZeit.
Since all dates are calculated as days passed since 1900-01-01, adding '1899-12-30 11:11:11' to that date, and adding '1901-01-01 11:11:11' to the same date produces different dates!
Date '1899-12-30' is interpreted as day -2, while '1900-01-01' is interpreted as day 0.
See Last Post!
N 56°04'39.16"
E 12°55'05.25"
June 20, 2006 at 9:22 am
Hi,
I not really sure about what you're asking but it seems you're 'pro-rating' the number of hours being worked according to some attribute of the date, thus the problem appears to similar to a problem of paying 'Overtime'.
If this is so the case statement might be of help to you, in example,
Select EmployeeNo, sum((case when DateType='HolidayWeekEnd' then hours * rate1 when DateType of 'WeekEnd' then hours* rate2 else hours end)) 'HourstoPay' from tblTable
where Dates between @DateOne and @DateTwo
Hope this helps
Dan
June 20, 2006 at 10:44 am
N 56°04'39.16"
E 12°55'05.25"
June 21, 2006 at 2:56 am
Here is the breakdown of the test data
LoginDate | LoginZeit | LogoutDate | LogoutZeit | Diff | 00-06 | 06-22 | 22-24 | 00-06 | |||
2006-05-24 | 00:59:47 | 2006-05-24 | 01:09:00 | 553 | 553 | ||||||
2006-05-24 | 07:58:57 | 2006-05-24 | 15:30:05 | 27 068 | 27 068 | ||||||
2006-05-24 | 08:41:12 | 2006-05-24 | 13:00:41 | 15 569 | 15 569 | ||||||
2006-05-24 | 09:29:08 | 2006-05-24 | 11:33:03 | 7 435 | 7 435 | ||||||
2006-05-24 | 10:01:02 | 2006-05-24 | 16:30:04 | 23 342 | 23 342 | ||||||
2006-05-24 | 13:00:37 | 2006-05-24 | 16:16:18 | 11 741 | 11 741 | ||||||
2006-05-24 | 13:32:24 | 2006-05-24 | 20:30:00 | 25 056 | 25 056 | ||||||
2006-05-24 | 13:56:27 | 2006-05-24 | 20:30:08 | 23 621 | 23 621 | ||||||
2006-05-24 | 13:57:32 | 2006-05-24 | 18:15:32 | 15 480 | 15 480 | ||||||
2006-05-24 | 13:59:18 | 2006-05-24 | 17:31:59 | 12 761 | 12 761 | ||||||
2006-05-24 | 13:59:32 | 2006-05-24 | 17:14:57 | 11 725 | 11 725 | ||||||
2006-05-24 | 13:59:40 | 2006-05-24 | 16:15:23 | 8 143 | 8 143 | ||||||
2006-05-24 | 14:00:41 | 2006-05-24 | 17:31:20 | 12 639 | 12 639 | ||||||
2006-05-24 | 14:01:01 | 2006-05-24 | 20:30:04 | 23 343 | 23 343 | ||||||
2006-05-24 | 14:02:00 | 2006-05-24 | 17:24:39 | 12 159 | 12 159 | ||||||
2006-05-24 | 16:59:19 | 2006-05-24 | 21:10:12 | 15 053 | 15 053 | ||||||
2006-05-24 | 17:54:12 | 2006-05-24 | 22:16:54 | 15 762 | 14 748 | 1 014 | |||||
2006-05-24 | 18:44:19 | 2006-05-25 | 00:00:50 | 18 991 | 11 741 | 7 200 | 50 | ||||
2006-05-24 | 18:59:30 | 2006-05-24 | 22:14:38 | 11 708 | 10 830 | 878 | |||||
2006-05-24 | 18:59:45 | 2006-05-24 | 22:14:52 | 11 707 | 10 815 | 892 | |||||
2006-05-24 | 19:59:20 | 2006-05-25 | 01:13:21 | 18 841 | 7 240 | 7 200 | 4401 | ||||
2006-05-24 | 19:59:41 | 2006-05-25 | 00:15:51 | 15 370 | 7 219 | 7 200 | 951 | ||||
2006-05-24 | 20:00:11 | 2006-05-25 | 01:15:11 | 18 900 | 7 189 | 7 200 | 4511 | ||||
2006-05-24 | 20:01:09 | 2006-05-24 | 21:59:15 | 7 086 | 7 086 | ||||||
2006-05-24 | 22:50:31 | 2006-05-25 | 02:31:34 | 13 263 | 4 169 | 9094 | |||||
25 | 377 316 | 553 | 322 003 | 35 753 | 19 007 | 377 316 | Zeit | ||||
1 | 23 | 8 | 5 | 37 | Anzahl |
And here is the test data
-- Populate test data
DECLARE @LoginLogout TABLE
(
Site VARCHAR(55), LoginID INT, NST DECIMAL(10, 0), LoginZeit DATETIME, LogoutZeit DATETIME, LogoutDate DATETIME, Skill1 DECIMAL(5, 0) NULL, Skill2 DECIMAL(5, 0) NULL, Skill3 DECIMAL(5, 0) NULL, DiffInOut INT, Logindate DATETIME
)
INSERT @LoginLogout
(
Site, LoginID, NST, LoginZeit, LogoutZeit, LogoutDate, Skill1, Skill2, Skill3, DiffInOut, Logindate
)
SELECT 'Siteone', 50001, 74587, '1899-12-30 20:01:09.000', '1899-12-30 21:59:15.000', '2006-05-24 00:00:00.000', 100, NULL, NULL, 7086, '2006-05-24 00:00:00.000' UNION ALL
SELECT 'Siteone', 50001, 74628, '1899-12-30 09:29:08.000', '1899-12-30 11:33:03.000', '2006-05-24 00:00:00.000', 100, NULL, NULL, 7435, '2006-05-24 00:00:00.000' UNION ALL
SELECT 'Siteone', 50002, 74558, '1899-12-30 13:59:18.000', '1899-12-30 17:31:59.000', '2006-05-24 00:00:00.000', 100, NULL, NULL, 12761, '2006-05-24 00:00:00.000' UNION ALL
SELECT 'Siteone', 50006, 74534, '1899-12-30 22:50:31.000', '1899-12-30 02:31:34.000', '2006-05-25 00:00:00.000', 100, NULL, NULL, 13263, '2006-05-24 00:00:00.000' UNION ALL
SELECT 'Siteone', 50007, 74511, '1899-12-30 13:57:32.000', '1899-12-30 18:15:32.000', '2006-05-24 00:00:00.000', 100, NULL, NULL, 15480, '2006-05-24 00:00:00.000' UNION ALL
SELECT 'Siteone', 50010, 74596, '1899-12-30 13:59:32.000', '1899-12-30 17:14:57.000', '2006-05-24 00:00:00.000', 100, NULL, NULL, 11725, '2006-05-24 00:00:00.000' UNION ALL
SELECT 'Siteone', 50011, 74538, '1899-12-30 14:02:00.000', '1899-12-30 17:24:39.000', '2006-05-24 00:00:00.000', 100, NULL, NULL, 12159, '2006-05-24 00:00:00.000' UNION ALL
SELECT 'Siteone', 50011, 74538, '1899-12-30 18:59:45.000', '1899-12-30 22:14:52.000', '2006-05-24 00:00:00.000', 100, NULL, NULL, 11707, '2006-05-24 00:00:00.000' UNION ALL
SELECT 'Siteone', 50014, 74518, '1899-12-30 13:59:40.000', '1899-12-30 16:15:23.000', '2006-05-24 00:00:00.000', 100, NULL, NULL, 8143, '2006-05-24 00:00:00.000' UNION ALL
SELECT 'Siteone', 50014, 74518, '1899-12-30 16:59:19.000', '1899-12-30 21:10:12.000', '2006-05-24 00:00:00.000', 100, NULL, NULL, 15053, '2006-05-24 00:00:00.000' UNION ALL
SELECT 'Siteone', 50016, 74680, '1899-12-30 18:44:19.000', '1899-12-30 00:00:50.000', '2006-05-25 00:00:00.000', 100, NULL, NULL, 18991, '2006-05-24 00:00:00.000' UNION ALL
SELECT 'Siteone', 50018, 74539, '1899-12-30 18:59:30.000', '1899-12-30 22:14:38.000', '2006-05-24 00:00:00.000', 100, NULL, NULL, 11708, '2006-05-24 00:00:00.000' UNION ALL
SELECT 'Siteone', 50019, 74585, '1899-12-30 08:41:12.000', '1899-12-30 13:00:41.000', '2006-05-24 00:00:00.000', 100, NULL, NULL, 15569, '2006-05-24 00:00:00.000' UNION ALL
SELECT 'Siteone', 50020, 74519, '1899-12-30 07:58:57.000', '1899-12-30 15:30:05.000', '2006-05-24 00:00:00.000', 100, NULL, NULL, 27068, '2006-05-24 00:00:00.000' UNION ALL
SELECT 'Siteone', 50025, 74628, '1899-12-30 13:00:37.000', '1899-12-30 16:16:18.000', '2006-05-24 00:00:00.000', 100, NULL, NULL, 11741, '2006-05-24 00:00:00.000' UNION ALL
SELECT 'Siteone', 50030, 74632, '1899-12-30 13:32:24.000', '1899-12-30 20:30:00.000', '2006-05-24 00:00:00.000', 100, NULL, NULL, 25056, '2006-05-24 00:00:00.000' UNION ALL
SELECT 'Siteone', 50033, 74545, '1899-12-30 00:59:47.000', '1899-12-30 01:09:00.000', '2006-05-24 00:00:00.000', 100, NULL, NULL, 553, '2006-05-24 00:00:00.000' UNION ALL
SELECT 'Siteone', 50033, 74690, '1899-12-30 19:59:41.000', '1899-12-30 00:15:51.000', '2006-05-25 00:00:00.000', 100, NULL, NULL, 15370, '2006-05-24 00:00:00.000' UNION ALL
SELECT 'Siteone', 50034, 74599, '1899-12-30 20:00:11.000', '1899-12-30 01:15:11.000', '2006-05-25 00:00:00.000', 100, NULL, NULL, 18900, '2006-05-24 00:00:00.000' UNION ALL
SELECT 'Siteone', 50037, 74618, '1899-12-30 14:01:01.000', '1899-12-30 20:30:04.000', '2006-05-24 00:00:00.000', 100, NULL, NULL, 23343, '2006-05-24 00:00:00.000' UNION ALL
SELECT 'Siteone', 50041, 74681, '1899-12-30 10:01:02.000', '1899-12-30 16:30:04.000', '2006-05-24 00:00:00.000', 100, NULL, NULL, 23342, '2006-05-24 00:00:00.000' UNION ALL
SELECT 'Siteone', 50045, 74597, '1899-12-30 19:59:20.000', '1899-12-30 01:13:21.000', '2006-05-25 00:00:00.000', 100, NULL, NULL, 18841, '2006-05-24 00:00:00.000' UNION ALL
SELECT 'Siteone', 50046, 74561, '1899-12-30 13:56:27.000', '1899-12-30 20:30:08.000', '2006-05-24 00:00:00.000', 100, NULL, NULL, 23621, '2006-05-24 00:00:00.000' UNION ALL
SELECT 'Siteone', 50048, 74687, '1899-12-30 17:54:12.000', '1899-12-30 22:16:54.000', '2006-05-24 00:00:00.000', 100, NULL, NULL, 15762, '2006-05-24 00:00:00.000' UNION ALL
SELECT 'Siteone', 50053, 74520, '1899-12-30 14:00:41.000', '1899-12-30 17:31:20.000', '2006-05-24 00:00:00.000', 100, NULL, NULL, 12639, '2006-05-24 00:00:00.000'
DECLARE @fhessen TABLE
(
feiertage datetime
)
INSERT @fhessen
(
feiertage
)
SELECT '2006-05-25'
And here is the function
CREATE FUNCTION dbo.fnCalculateSeconds
(
@LoginDate DATETIME,
@LoginZeit DATETIME,
@LogoutDate DATETIME,
@LogoutZeit DATETIME,
@InTime DATETIME,
@OutTime DATETIME,
@FromCheck BIT
)
RETURNS INT
AS
BEGIN
DECLARE @Login DATETIME,
@Logout DATETIME,
@Low DATETIME,
@High DATETIME,
@Seconds INT
SELECT @Login = DATEADD(dd, DATEDIFF(dd, 0, @LoginDate), 0) + DATEADD(dd, -DATEDIFF(dd, 0, @LoginZeit), @LoginZeit),
@Logout = DATEADD(dd, DATEDIFF(dd, 0, @LogoutDate), 0) + DATEADD(dd, -DATEDIFF(dd, 0, @LogoutZeit), @LogoutZeit)
IF @FromCheck = 1
SELECT @Low = DATEADD(dd, DATEDIFF(dd, 0, @login), 0) + DATEADD(dd, -DATEDIFF(dd, 0, @InTime), @InTime),
@High = DATEADD(dd, DATEDIFF(dd, 0, @login), 0) + DATEADD(dd, -DATEDIFF(dd, 0, @OutTime), @OutTime) + DATEADD(ss, 1, 0)
ELSE
SELECT @Low = DATEADD(dd, DATEDIFF(dd, 0, @Logout), 0) + DATEADD(dd, -DATEDIFF(dd, 0, @InTime), @InTime),
@High = DATEADD(dd, DATEDIFF(dd, 0, @Logout), 0) + DATEADD(dd, -DATEDIFF(dd, 0, @OutTime), @OutTime) + DATEADD(ss, 1, 0)
IF @login <= @Low AND @Low <= @High AND @High <= @Logout
SELECT @Seconds = DATEDIFF(ss, @Low, @High)
IF @Low <= @login AND @login <= @Logout AND @Logout <= @High
SELECT @Seconds = DATEDIFF(ss, @login, @Logout)
IF @login <= @Low AND @Low <= @Logout AND @Logout <= @High
SELECT @Seconds = DATEDIFF(ss, @Low, @Logout)
IF @Low <= @login AND @login <= @High AND @High <= @Logout
SELECT @Seconds = DATEDIFF(ss, @login, @High)
IF @FromCheck = 0 AND DATEDIFF(dd, @LoginDate, @LogoutDate) = 0
SELECT @Seconds = 0
RETURN ISNULL(@Seconds, 0)
END
And here is the code
--Do the magic!
SELECT z.theDate,
z.Vacation,
z.Sonntag,
SUM(case when z.[00-06] > 0 then 1 else 0 end) 'Anzahl 00-06',
SUM(case when z.[06-22] > 0 then 1 else 0 end) 'Anzahl 06-22',
SUM(case when z.[22-24] > 0 then 1 else 0 end) 'Anzahl 22-24',
SUM(z.[00-06]) 'Zeit 00-06',
SUM(z.[06-22]) 'Zeit 06-22',
SUM(z.[22-24]) 'Zeit 22-24'
FROM (
SELECT ll.LoginDate theDate,
ll.loginzeit,
CASE WHEN fh.feiertage IS NULL THEN 0 ELSE 1 END Vacation,
CASE WHEN DATEPART(dw, ll.LoginDate) = 1 THEN 1 ELSE 0 END Sonntag,
dbo.fnCalculateSeconds(ll.LoginDate, ll.LoginZeit, ll.LogoutDate, ll.LogoutZeit, '00:00:00', '05:59:59', 1) '00-06',
dbo.fnCalculateSeconds(ll.LoginDate, ll.LoginZeit, ll.LogoutDate, ll.LogoutZeit, '06:00:00', '21:59:59', 1) '06-22',
dbo.fnCalculateSeconds(ll.LoginDate, ll.LoginZeit, ll.LogoutDate, ll.LogoutZeit, '22:00:00', '23:59:59', 1) '22-24'
FROM @LoginLogout ll
LEFT JOIN @fhessen fh ON fh.feiertage = ll.LoginDate
UNION ALL
SELECT ll.LogoutDate theDate,
ll.logoutzeit,
CASE WHEN fh.feiertage IS NULL THEN 0 ELSE 1 END,
CASE WHEN DATEPART(dw, ll.LogoutDate) = 1 THEN 1 ELSE 0 END,
dbo.fnCalculateSeconds(ll.LoginDate, ll.LoginZeit, ll.LogoutDate, ll.LogoutZeit, '00:00:00', '05:59:59', 0),
dbo.fnCalculateSeconds(ll.LoginDate, ll.LoginZeit, ll.LogoutDate, ll.LogoutZeit, '06:00:00', '21:59:59', 0),
dbo.fnCalculateSeconds(ll.LoginDate, ll.LoginZeit, ll.LogoutDate, ll.LogoutZeit, '22:00:00', '23:59:59', 0)
FROM @LoginLogout ll
LEFT JOIN @fhessen fh ON fh.feiertage = ll.LogoutDate
) z
GROUP BY z.theDate,
z.Vacation,
z.Sonntag
And here is the output
theDate Vacation Sonntag Anzahl 00-06 Anzahl 06-22 Anzahl 22-24 Zeit 00-06 Zeit 06-22 Zeit 22-24
---------- -------- ------- ------------ ------------ ------------ ----------- ----------- -----------
2006-05-24 0 0 1 23 8 553 322003 35753
2006-05-25 1 0 5 0 0 19007 0 0
N 56°04'39.16"
E 12°55'05.25"
June 21, 2006 at 5:49 am
Hallo sorry for answere so late but there are Problems with the Inernet from the IT Service. I take all from you and it RUNS very well.
Thank you for spent your time for me.
Ok i am Newbie but it looks SUPER.
Thanks again
Thomas
June 21, 2006 at 6:22 am
Thanks! I hope the code works out for you.
If you have the time and courage, I would suggest another environment for you, since your environment has a number of flaws. For example logging in 2006-05-24 23:50:00 and logging out 2006-05-26 00:15:00 can't be done. The algorithm will not work correctly. But my proposed environment will take just about anything.
First of all, I would have a lookup table with all information about dates like this
DECLARE @times TABLE (FromTime DATETIME, ToTime DATETIME, Vacation BIT, Salary SMALLMONEY, Timeslot VARCHAR(8))
INSERT @times
SELECT '2006-05-24 00:00:00', '2006-05-24 05:59:59', 0, 1.25, '00-06' UNION ALL
SELECT '2006-05-24 06:00:00', '2006-05-24 21:59:59', 0, 1.00, '06-22' UNION ALL
SELECT '2006-05-24 22:00:00', '2006-05-24 23:59:59', 0, 1.25, '22-24' UNION ALL
SELECT '2006-05-25 00:00:00', '2006-05-25 23:59:59', 1, 2.00, '00-24' UNION ALL
SELECT '2006-05-26 00:00:00', '2006-05-26 05:59:59', 0, 1.50, '00-06'
Then I would have a table containing all the logins and logout for the workers
DECLARE @Logs TABLE (WorkerID INT, Login DATETIME, Logout DATETIME)
INSERT @Logs
SELECT 1000, '2006-05-24 04:00:00', '2006-05-25 01:30:00' UNION ALL
SELECT 1000, '2006-05-26 08:00:00', '2006-05-26 17:00:00' UNION ALL
SELECT 1001, '2006-05-24 13:30:00', '2006-05-24 20:00:00' UNION ALL
SELECT 1001, '2006-05-25 10:15:00', '2006-05-25 16:30:00'
For your current environment, it took a function and a lot of programming to accomplish the task you wanted. But look at my proposed environment! There is no need for a function, just a simple select
SELECT l.WorkerID,
t.Vacation IsVacation,
DATEADD(dd, DATEDIFF(dd, 0, t.FromTime), 0) WorkDate,
t.Timeslot,
CASE
WHEN t.FromTime <= l.Login AND l.Login <= t.ToTime AND t.ToTime <= l.Logout THEN 1 + DATEDIFF(ss, l.Login, t.ToTime)
WHEN t.FromTime <= l.Login AND l.Login <= l.Logout AND l.Logout <= t.ToTime THEN DATEDIFF(ss, l.Login, l.Logout)
WHEN l.Login <= t.FromTime AND t.FromTime <= l.Logout AND l.Logout <= t.ToTime THEN DATEDIFF(ss, t.FromTime, l.Logout)
WHEN l.Login <= t.FromTime AND t.FromTime <= t.ToTime AND t.ToTime <= l.Logout THEN 1 + DATEDIFF(ss, t.FromTime, t.ToTime)
END WorkSeconds,
t.Salary WorkSalary
FROM @Logs l
CROSS JOIN @Times t
WHERE (t.FromTime <= l.Login AND l.Login <= t.ToTime AND t.ToTime <= l.Logout)
OR (t.FromTime <= l.Login AND l.Login <= l.Logout AND l.Logout <= t.ToTime)
OR (l.Login <= t.FromTime AND t.FromTime <= l.Logout AND l.Logout <= t.ToTime)
OR (l.Login <= t.FromTime AND t.FromTime <= t.ToTime AND t.ToTime <= l.Logout)
ORDER BY l.WorkerID,
l.Login,
t.FromTime
And there is another benefit! You can also retreive the salary information related to the timeslot. Output from my proposed environment is
WorkerID IsVacation WorkDate Timeslot WorkSeconds WorkSalary Payment
-------- ---------- ---------- -------- ----------- ---------- -------
1000 0 2006-05-24 00-06 7200 1.25 50.00
1000 0 2006-05-24 06-22 57600 1.00 320.00
1000 0 2006-05-24 22-24 7200 1.25 50.00
1000 1 2006-05-25 00-24 5400 2.00 60.00
1001 0 2006-05-24 06-22 23400 1.00 146.25
1001 1 2006-05-25 00-24 22500 2.00 281.25
Keep in mind that this only select can be put into a stored procedure where the call parameters can be fromdate and to date such as
EXEC uspGetTimeReport '2006-05-01', '2006-05-31'
or any other date. And you can really easy produce a report for salary payment! Join the table to the Workers table where the personal hourly payment is stored and multiply with WorkSalary value and multiply with WorkSeconds / 3600.0, and you get exactly what to pay each worker. Of course you then also have the opportunity to do a round off for the times. If wanted, you can round off to nearest 10 minutes up (600 seconds). If worker did 5 minutes and 30 seconds in one timeslot, round up to 10 minutes even, or 30 minutes, or not at all! Se table above. No round off and Worker 1000 has 20 euro an hour and Worker 1001 has 22.50 euro an hour.
Good luck and have a nice day!
N 56°04'39.16"
E 12°55'05.25"
Viewing 10 posts - 16 through 24 (of 24 total)
You must be logged in to reply to this topic. Login to reply