My goal is to generate a report that will provide me with data to submit to a payroll company.
Our pay periods are the 1st through the 15th and then the 16th through the end of the month and I can easily generate a report that shows how many hours an employee works between those given dates.
My problem is with overtime. Overtime is calculated based on an employees work in a given week. Our week start and end dates are Sunday through Saturday. Here is a specific example of the challenge.
The pay period that ends on 2016-01-31 is part of weeks 3, 4, 5 and 6. It has seven days in week 4 and 5, and only one day in week 3 and 6. I would like to pay (on this particular pay period) any overtime the employee worked in weeks 3, 4 and 5. I will pay them for week 6 overtime in the next pay period once that week is complete.
I need a little help. Specifically a direction to start looking. Would this be a situation where I would embed a SELECT within a SELECT? Since I am operating on two different spins on the same data source ... I am a little baffled.
Anyone have any experience here? Thoughts?
Report for Pay Period Ending 2016-01-31
Employee Hours OT Hr
----------------------- ------- -------
Joe Employee 95.00 1.00
- Week 3 (1 Day) 7.00 1.00
- Week 4 (7 Days) 40.00 0.00
- Week 5 (7 Days) 40.00 0.00
- Week 6 (1 Day) 8.00 0.00
This sample report shows that an employee worked 96 hours over 16 days during the pay period ending 2016-01-31. The one hour of overtime and 7 hours of regular time in week 3 suggests they worked extra on hours in the previous pay period that propelled their week 3 total hours over 40.
Business Rule: Overtime is paid for an employees hours that exceed 40 during a week. Weeks are defined as the time from Sunday to Saturday. Payments are made on Pay Dates. Pay Dates are defined as the 15th and last day of each month. If a Pay Period occurs in the middle of a week. Employees are paid for overtime hours on both side of the pay date as defined above.
Sample Data as Requested
Employee Start End Week PayPeriod Duration
John Employee 2016-01-02 09:23:42 2016-01-02 15:13:43 1 1/15/2016 5.83
John Employee 2016-01-04 09:42:30 2016-01-04 17:58:19 2 1/15/2016 8.26
John Employee 2016-01-05 09:46:04 2016-01-05 13:30:03 2 1/15/2016 3.73
John Employee 2016-01-05 14:03:02 2016-01-05 18:06:34 2 1/15/2016 4.06
John Employee 2016-01-06 10:30:43 2016-01-06 17:14:18 2 1/15/2016 6.73
John Employee 2016-01-07 10:05:22 2016-01-07 13:43:59 2 1/15/2016 3.64
John Employee 2016-01-07 14:14:20 2016-01-07 18:05:50 2 1/15/2016 3.86
John Employee 2016-01-08 09:55:59 2016-01-08 17:47:58 2 1/15/2016 7.87
John Employee 2016-01-11 10:28:22 2016-01-11 17:54:04 3 1/15/2016 7.43
John Employee 2016-01-12 09:33:30 2016-01-12 10:08:43 3 1/15/2016 0.59
John Employee 2016-01-12 10:39:59 2016-01-12 18:29:24 3 1/15/2016 7.82
John Employee 2016-01-13 10:41:16 2016-01-13 13:39:29 3 1/15/2016 2.97
John Employee 2016-01-13 13:39:29 2016-01-13 15:05:05 3 1/15/2016 1.43
John Employee 2016-01-13 15:05:06 2016-01-13 17:25:30 3 1/15/2016 2.34
John Employee 2016-01-14 10:32:28 2016-01-14 14:01:33 3 1/15/2016 3.48
John Employee 2016-01-14 14:20:47 2016-01-14 18:07:42 3 1/15/2016 3.78
John Employee 2016-01-15 09:40:31 2016-01-15 17:19:34 3 1/15/2016 7.65
John Employee 2016-01-16 09:40:31 2016-01-16 17:19:34 3 1/31/2016 7.65
John Employee 2016-01-18 10:01:39 2016-01-18 15:40:43 4 1/31/2016 5.65
John Employee 2016-01-18 15:53:38 2016-01-18 18:38:27 4 1/31/2016 2.75
John Employee 2016-01-19 10:43:24 2016-01-19 18:13:04 4 1/31/2016 7.49
John Employee 2016-01-20 10:38:38 2016-01-20 14:16:09 4 1/31/2016 3.63
John Employee 2016-01-20 14:16:09 2016-01-20 17:55:07 4 1/31/2016 3.65
John Employee 2016-01-21 10:39:31 2016-01-21 18:56:42 4 1/31/2016 8.29
John Employee 2016-01-22 10:57:55 2016-01-22 15:44:03 4 1/31/2016 4.77
John Employee 2016-01-22 15:57:54 2016-01-22 18:11:28 4 1/31/2016 2.23
John Employee 2016-01-25 10:08:57 2016-01-25 19:14:21 5 1/31/2016 9.09
John Employee 2016-01-26 10:45:35 2016-01-26 14:17:13 5 1/31/2016 3.53
John Employee 2016-01-26 14:40:51 2016-01-26 18:31:56 5 1/31/2016 3.85
John Employee 2016-01-27 09:53:33 2016-01-27 18:05:40 5 1/31/2016 8.20
John Employee 2016-01-28 10:36:57 2016-01-28 16:28:16 5 1/31/2016 5.86
John Employee 2016-01-28 16:43:20 2016-01-28 19:42:17 5 1/31/2016 2.98
John Employee 2016-01-31 10:00:40 2016-01-31 16:27:46 6 1/31/2016 6.45
John Employee 2016-02-01 10:45:42 2016-02-01 14:04:03 6 2/15/2016 3.31
John Employee 2016-02-01 14:15:06 2016-02-01 17:45:05 6 2/15/2016 3.50
John Employee 2016-02-01 17:45:05 2016-02-01 19:01:34 6 2/15/2016 1.27
John Employee 2016-02-02 11:03:49 2016-02-02 17:40:21 6 2/15/2016 6.61
John Employee 2016-02-03 11:08:06 2016-02-03 17:15:38 6 2/15/2016 6.13
John Employee 2016-02-04 11:20:59 2016-02-04 17:27:15 6 2/15/2016 6.10
John Employee 2016-02-04 17:27:15 2016-02-04 20:19:34 6 2/15/2016 2.87
John Employee 2016-02-05 10:47:57 2016-02-05 17:53:54 6 2/15/2016 7.10
John Employee 2016-02-08 10:51:45 2016-02-08 15:15:28 7 2/15/2016 4.40
John Employee 2016-02-08 15:34:52 2016-02-08 17:30:54 7 2/15/2016 1.93
John Employee 2016-02-09 11:01:09 2016-02-09 13:11:02 7 2/15/2016 2.16
John Employee 2016-02-09 13:11:02 2016-02-09 17:38:03 7 2/15/2016 4.45
John Employee 2016-02-09 17:38:03 2016-02-09 18:34:20 7 2/15/2016 0.94
John Employee 2016-02-10 10:43:39 2016-02-10 11:25:38 7 2/15/2016 0.70
John Employee 2016-02-10 11:25:38 2016-02-10 17:58:11 7 2/15/2016 6.54
John Employee 2016-02-11 10:16:30 2016-02-11 14:06:35 7 2/15/2016 3.83
John Employee 2016-02-11 14:30:17 2016-02-11 17:25:23 7 2/15/2016 2.92
John Employee 2016-02-12 10:46:50 2016-02-12 17:46:38 7 2/15/2016 7.00
I need to pay 5.15 hours of overtime in PayPeriod 2016-01-15 because he did not go over 40 until after the 2015-01-15 pay period closed.
If the employee had crossed over 40 hours before the 2016-01-15 pay period closed, I would have needed to pay overtime on both the 2016-01-15 and the 2016-01-31 pay periods for week three hours.
Here's my thought on overtime calculation:
you'll start checking the start date for the period, which day is it? If it is not Sunday, that means you need to pay some overtime for earlier dates? Well, for how many days? You'll always start from the sunday of that week for calculating the overtime for that week. Some useful mySql functions here are: DAYOFWEEK() and DATE_ADD()
Then you'll continue until the end date for that period is reached/passed, and you'll calculate the overtime for each week (sunday-saturday). If a saturday is passed your end date for the payroll period, you'll just skip that week for your overtime calculation.
Related
I have a table in MYSQL(version 5.7.33) which looks like shown below:
Date
SalesRep
Sale
2021-04-01
Jack
10
2021-04-02
Jack
8
2021-03-01
Lisa
10
2021-03-02
Lisa
14
2021-03-03
Lisa
21
2021-03-04
Lisa
7
2021-03-08
Lisa
10
2021-03-09
Lisa
20
2021-03-10
Lisa
15
I want the moving average of Sale column, but don't want that to be based on the dates since the dates have gap, instead I want it based on row numbers and grouped by SalesRep. So something like this:
Date
SalesRep
Sale
MoveAvg
2021-04-01
Jack
10
10
2021-04-02
Jack
8
9
2021-03-01
Lisa
10
10
2021-03-02
Lisa
14
12
2021-03-03
Lisa
21
15
2021-03-04
Lisa
7
13
2021-03-08
Lisa
10
12.4
2021-03-09
Lisa
20
13.6
2021-03-10
Lisa
15
13.8
So the moving average is for all the dates from start to finish for a particular sales rep and then it starts over for another sales rep and so on. Is this possible to do in MYSQL? Thank you in advance!
You could use avg as a window function with a frame clause for this:
SELECT dt, salesrep, sale,
AVG(sale) OVER (PARTITION BY salesrep ORDER BY dt
ROWS UNBOUNDED PRECEDING)
AS moveavg
Without window functions, you simply join all previous rows for each salesrep:
select a.dt, a.salesrep, a.sale, avg(b.sale) as moveavg
from mysterytablename a
join mysterytablename b on b.salesrep=a.salesrep and b.dt <= a.dt
group by a.salesrep, a.dt
Sorry for my bad english. I have a database
Id Personel_ID DateTime
1 1 21.02.2018 07:31:00
2 1 21.02.2018 08:20:00
3 1 21.02.2018 18:15:00
4 2 21.02.2018 07:15:00
5 2 21.02.2018 07:18:00
6 2 21.02.2018 16:25:00
7 2 21.02.2018 18:29:00
8 1 22.02.2018 08:32:00
9 1 22.02.2018 08:42:00
10 1 22.02.2018 17:00:00
11 1 22.02.2018 18:01:00
12 2 22.02.2018 08:20:00
13 2 22.02.2018 09:10:00
14 2 22.02.2018 17:50:00
What I want to do is
Id Personel_ID Date Login Time Logout Time
1 1 21.02.2018 07:31:00 18:15:00
2 2 21.02.2018 07:15:00 18:29:00
3 1 22.02.2018 08:32:00 18:01:00
4 2 22.02.2018 08:20:00 17:50:00
I want to get a Personel_ID's first record of a date as login time and last record of a date is logout time. I hope you understand
It could be:
Select
Personel_ID,
DateValue([DateTime]) As [Date],
Min(TimeValue([DateTime])) As [Login Time],
Max(TimeValue([DateTime])) As [Logout Time]
From
YourTable
Group By
Personel_ID,
DateValue([DateTime])
The table "commissions" is of this form:
affiliate referral amount date
3 2 15 2016-08-27
1 22 10 2016-08-29
4 45 5 2016-09-06
1 33 9 2016-09-08
3 17 4 2016-09-11
2 33 10 2016-09-16
1 9 7 2016-09-26
3 17 9 2016-09-26
2 69 10 2016-09-30
1 21 7 2016-10-01
4 55 2 2016-10-06
I need to find out the ranking of the affiliates with most commissions month to month.
I have tried:
SELECT affiliate, SUM(amount) as amount
FROM commissions
GROUP BY affiliate, YEAR(date), MONTH(date)
But unfortunately it is not throwing the desired results.
Please help.
I've been working on a MySQL query that sorts data into weeks but I just can't figure out how to do it.
I would like to sort the data into weeks for the current and last 11 weeks. Each week will run from Monday 00:00:00 to Sunday 23:59:59.
(Taking todays date as 2014-12-04)...
Week 1: 2014-12-01 > 2014-12-07 - (Last Monday 00:00:00 to next Sunday 23:59:59)
Week 2: 2014-11-24 > 2014-11-30 - (Monday before last 00:00:00 to last Sunday 23:59:59)
Week 3: 2014-11-17 > 2014-11-23 - (Monday before before last 00:00:00 to last last Sunday 23:59:59)
And so on...
For each week the value field data will be totalled.
I need the data returned to be in the format:
datetime: The first date (Always a Monday) of that week.
value: The total of all the values in that week.
For example, the returned data:
Week 1: 2014-12-01 : Totalled value=11
Week 2: 2014-11-24 : Totalled value=3
Week 3: 2014-11-17 : Totalled value=9
Week 4: 2014-11-10 : Totalled value=7
Table_1 data:
table1id datetime value
1 2014-09-01 06:00:00 4
2 2014-09-04 17:00:00 6
3 2014-09-09 18:00:00 9
4 2014-09-15 07:00:00 4
5 2014-09-20 10:00:00 2
6 2014-09-25 10:00:00 3
7 2014-09-30 09:00:00 8
8 2014-10-01 14:00:00 5
9 2014-10-05 10:00:00 7
10 2014-10-09 18:00:00 3
11 2014-10-15 05:00:00 4
12 2014-10-20 07:00:00 8
13 2014-10-24 16:00:00 9
14 2014-10-29 15:00:00 5
15 2014-10-31 16:00:00 7
16 2014-11-05 09:00:00 2
17 2014-11-10 08:00:00 4
18 2014-11-15 16:00:00 3
19 2014-11-20 10:00:00 9
20 2014-11-25 10:00:00 2
21 2014-11-30 10:00:00 1
22 2014-12-01 15:00:00 7
23 2014-12-04 18:00:00 2
I 'could' just pull all the data unsorted for the date range using PHP and sort it from there but I'd rather the MySQL server do it.
Any suggestions would be greatly appreciated. :-)
based on generate days from date range
you can do smething like that:
select mondays.week, mondays.day, sum(value)
from
(select a.a+1 week, curdate() - WEEKDAY(curdate()) - INTERVAL (7*a.a) DAY as day from (select 0 as a union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9 union all select 10 union all select 11) as a) as mondays,
Table_1
where Table_1.datetime between mondays.day and (mondays.day + interval(7) day)
group by mondays.week, mondays.day;
Query for VB6 and MS Access
Table:-
User Id LogDate LogTime
1 1/1/2010 9:00
1 1/1/2010 10:00
1 1/1/2010 11:29
1 2/1/2010 10:00
2 2/1/2010 22:00
2 3/1/2010 11:00
Need to display as:-
User Id LogDate LogTime LogDate LogTime
1 1/1/2010 9:00 1/1/2010 10:00
1 1/1/2010 11:29 2/1/2010 10:00
2 2/1/2010 22:00 3/1/2010 11:00
You need to use a sub-query to find the next date for a user, something like:
SELECT tblStackOverflowTimeQuery.lngUserId, tblStackOverflowTimeQuery.datLogDateTime,
(SELECT TOP 1 tblStackOverflowTimeQuery2.datLogDateTime
FROM tblStackOverflowTimeQuery AS tblStackOverflowTimeQuery2
WHERE tblStackOverflowTimeQuery.lngUserId = tblStackOverflowTimeQuery2.lngUserId
AND tblStackOverflowTimeQuery2.datLogDateTime > tblStackOverflowTimeQuery.datLogDateTime
ORDER BY tblStackOverflowTimeQuery2.datLogDateTime
) AS datEndDateTime
FROM tblStackOverflowTimeQuery
ORDER BY tblStackOverflowTimeQuery.lngUserId, tblStackOverflowTimeQuery.datLogDateTime;
That'll give the following:
lngUserId datLogDateTime datEndDateTime
1 01/01/2010 09:00:00 01/01/2010 10:00:00
1 01/01/2010 10:00:00 01/01/2010 11:29:00
1 01/01/2010 11:29:00 02/01/2010 10:00:00
1 02/01/2010 10:00:00
2 02/01/2010 22:00:00 03/01/2010 11:00:00
2 03/01/2010 11:00:00
which is not exactly what you wanted, but it's a start.
It would be easiest to do these things using code, but that would depend on how you want to use it. Presumably there's nothing in your data to indicate which entry is the start and which is the end.