Calculate actual working days for each month - sql

I am trying to calculate a factor for each employee and month. The factor depends on the actual working days.
For example to calculate it for April (4/1/2019 to 4/30/2019) one employee is on vacation from 4/8/2019 to 4/12/2019 and he will leave the company on the 4/26/2019.
April has 30 days and the employee has 5 days off and 4 days without contract (so hasn't the possibility to work for 9 days). In this case the factor would be 0.7 = (1/30)*(30-9).
How is it possible to count the clashing days for each month? It is also possible that an employee is on vacation from 3/25/2019 to 4/5/2019 etc.

Related

Why is Redshift datediff giving different weeks when it is the same number of day difference?

I'm trying to find the number of weeks between two days. When the difference is 8 days, I should be getting 1 or 2 weeks, depending on how the function works in Redshift (rounds up or down). However, it should be consistent whichever way it chooses.
I realize that I could simply take the number of days and then divide by 7 and do either a ROUND or a CEIL, but I am simply trying to understand why DATEDIFF(weeks, date1, date2) provides either 1 or 2 when I have the two dates different by 8 days.
SELECT
DATEDIFF(weeks, '2019-03-17', '2019-03-25') AS week_difference1,
DATEDIFF(days, '2019-03-17', '2019-03-25') AS day_difference1,
DATEDIFF(weeks, '2019-03-16', '2019-03-24') AS week_difference2,
DATEDIFF(days, '2019-03-16', '2019-03-24') AS day_difference2
Result:
week_difference1 = 1
day_difference1 = 8
week_difference2 = 2
day_difference2 = 8
As with many software products from the US, the first day of the week in Redshift (at least far as DATEDIFF is concerned) is Sunday, and not the ISO standard of Monday. Therefore when calculating the number of weeks between two dates the boundary is Saturday/Sunday.
In your example, the eight days between the 16th March 2019 and 24th March 2019 crosses two week boundaries (one on 16/17 March and one on 23/24 March), so the resulting DATEDIFF value is 2 (two week boundaries crossed).
However, the eight days between the 17th March and 25th March only crosses one week boundary (23/24 March) so the resulting DATEDIFF value is 1.

SQLite - Determine average sales made for each day of week

I am trying to produce a query in SQLite where I can determine the average sales made each weekday in the year.
As an example, I'd say like to say
"The average sales for Monday are $400.50 in 2017"
I have a sales table - each row represents a sale you made. You can have multiple sales for the same day. Columns that would be of interest here:
Id, SalesTotal, DayCreated, MonthCreated, YearCreated, CreationDate, PeriodOfTheDay
Day/Month/Year are integers that represent the day/month/year of the week. DateCreated is a unix timestamp that represents the date/time it was created too (and is obviously equal to day/month/year).
PeriodOfTheDay is 0, or 1 (day, or night). You can have multiple records for a given day (typically you can have at most 2 but some people like to add all of their sales in individually, so you could have 5 or more for a day).
Where I am stuck
Because you can have two records on the same day (i.e. a day sales, and a night sales, or multiple of each) I can't just group by day of the week (i.e. group all records by Saturday).
This is because the number of sales you made does not equal the number of days you worked (i.e. I could have worked 10 saturdays, but had 30 sales, so grouping by 'saturday' would produce 30 sales since 30 records exist for saturday (some just happen to share the same day)
Furthermore, if I group by daycreated,monthcreated,yearcreated it works in the sense it produces x rows (where x is the number of days you worked) however that now means I need to return this resultset to the back end and do a row count. I'd rather do this in the query so I can take the sales and divide it by the number of days you worked.
Would anyone be able to assist?
Thanks!
UPDATE
I think I got it - I would love someone to tell me if I'm right:
SELECT COUNT(DISTINCT CAST(( julianday((datetime(CreationDate / 1000, 'unixepoch', 'localtime'))) ) / 7 AS INT))
FROM Sales
WHERE strftime('%w', datetime(CreationDate / 1000, 'unixepoch'), 'localtime') = '6'
AND YearCreated = 2017
This would produce the number for saturday, and then I'd just put this in as an inner query, dividing the sale total by this number of days.
Buddy,
You can group your query by getting the day of week and week number of day created or creation date.
In MSSQL
DATEPART(WEEK,'2017-08-14') // Will give you week 33
DATEPART(WEEKDAY,'2017-08-14') // Will give you day 2
In MYSQL
WEEK('2017-08-14') // Will give you week 33
DAYOFWEEK('2017-08-14') // Will give you day 2
See this figures..
Day of Week
1-Sunday, 2- Monday, 3-Tuesday, 4-Wednesday, 5-Thursday, 6-Saturday
Week Number
1 - 53 Weeks in a year
This will be the key so that you will have a separate Saturday's in every month.
Hope this can help in building your query.

Oracle Query to get

Hi I have a peculiar requirement :
Generate a report calculating retention of customers for each week (last 8 week, week must start on mon and end on sun).
1) report is for 8 iso week (Mon-Sun), if I run report today i.e 10/23/2014 it should take data till 10/19/2014(week#42) back to 08/25/2014(week#35) and calculate retention for each week.So total 8 week...
This part I have completed using TRUNC(sysdate-7,'IW') & group by count for each week
But below point is getting harder for me
2) for each week the total cust count should be :
all the customers active before last day of previous week (i.e Sun of previous week)
for iso week 35
Start End : Calculate all the customers before 08/25/2014 -- A1
8/25/2014 8/31/2014
then calculate all customers who bought product in last 30 days i.e from 07/25/2014 to 08/24/2014. --A2
Retention % = A2/A1
the total for week 35 will be different
Start End : Calculate all the customers before 09/01/2014 --B1
9/1/2014 9/7/2014
then calculate all customers who bought product in last 30 days i.e from 08/01/2014 to 8/31/2014. --B2
Retention % = B2/B1

Need Excel Sheet to Calculate Complex Vacation Accrual and Use of Vacation Time

I've been working on this for a while and trying different styles... I need to develop a tracking spreadsheet (for 50 employees) that will calculate accruing vacation time and vacation time used based on the following parameters:
*Employees who have worked less than 3 years but past the 90 day anniversary with the company (at which they start accruing) (there is one more caveat on this... the accrual day is the 1st of the month of the month past the 90 days)[I figured this 90 day item out on my excel sheet] it will accrue at:
- 4 hours a month, at the end of the month, with a MAX cap of 72 hours that they can have stored (but if they use vacation time and fall below the 72 hours they can continue to accrue again up to 72 hours...)
*Employees who have worked more than 3 years but less than 6 years with the company carry over their prior vacation and begin to accrue from here onward at:
- 6.8 hours a month, at the end of the month, with a MAX cap of 122.4 hours that they can have stored (but if they use vacation time and fall below the 122.4 hours they can continue to accrue again up to 122.4 hours...)
*Employees 6 years and over with the company carry over their prior vacation and begin to accrue from here onward at:
- 10 hours a month, at the end of the month, with a MAX cap of 180 hours that they can have stored (but if they use vacation time and fall below the 180 hours they can continue to accrue again up to 180 hours....)
& yes, I need to be able to deduct vacation time used.
Does anyone have any suggestions for layout or for a formula that can do part of these functions? I appreciate any advice or suggestion on what else I can use!
I have created a test sheet, and was accruing based on these conditions for the first and started on the second set of rules (for years 3+).
However when I accrue to the max of 72 hours on the first policy, it no longer accrues correctly if they used vacation and fall under the 72 hours cap again.
I know this is a overcomplicated policy, but that is what the company wants and they will not budge.... Any help or advice is appreciated. I know my sheet isn't great.. but I'm trying options.
Below is the equation I used for the 90 day:
=IF(F2<TODAY()-90, F2+90, "90 Day Period")
Then to get the first day of the month after I used:
=IF(G2="90 Day Period","N/A",DATE(YEAR(G2),MONTH(G2)+1,1))
I tried using for the accrual of the first rule (but it has issues...):
=IF(N2="N/A","N/A",IF(N2<=36,MIN(72,((N2*4)-P2),72),(72-P2)))
For second rule:
=IF(AND(N2>36,N2<=72),MIN(122.4,((N2-36)*6.8)+Q2-S2),0)
Let
column A EmpName
column B EntryDate
Column C DaysSpent for the current month
Column D capped Accruel buffer at end of month
repeat Columns C and D month after month
example
01-Sep-2013 01-Oct-2013
EmpName EntryDate spent buffer spent buffer ... etc ...
.-------.-----------.-----------.------.-----------.------.
me 01-Jan-2010 0 12 0 18.8
you 01-Jun-2013 0 4 0 4
In order not to get spaghetti formulas I recommend to create some user defined functions in VBA, like
Function GetCap(EntryDate, ThisDate) As Single
Function GetMonthly(EntryDate, ThisDate) As Single
By experience it's easier to debug/maintain 2-3 nested If's or Select Case's in VBA than 92 character long formulas with no blanks, no comments etc. in the sheet. Should the business logic change, there's one code block to review - instead of dozens/hundreds of formula in a sheet that has grown for 3x12 months x 50 users.
The above functions may want the help of e.g.
Function EndOfMonth(MyDate) as Date
Function BeginOfNextMonth(MyDate) as Date
so that in the sheet you just
manually enter hours spent month after month
calculate new buffer as = MIN([oldbuffer] - [Spent] + GetMonthly(...), GetCap(...))
carefully use relative/absolute addressing to make the formula "copyable" across columns/rows, e.g.
row-absolute on ThisDate got from the header when copying downwards
column-absolute on EntryDate for each Emp when copying rightwards
You can of course use =GetCap(...) and =GetMonthly(...) directly in cells of your sheet to display intermediate results and for debugging purposes.
Be carefull when you compare dates
Tips:
3 years later is not always 365x3 days later
check what the VBA DateSerial() functions does for months > 12 and months < 0
the end of next month always is the first days of 2 months ahead minus 1 ... even in February of a leap year ggg
and post more questions if you get stuck on these functions.

billing module

I'm launching a small service and plan to charge monthly (eg- will be advertised as $10 monthly). I'm working on the billing module right now but was wondering about a small bit:
I plan to bill customers when they first register and then at regular intervals thereafter. Getting to my question- Some months have less than 30 days. Does monthly billing imply exactly a 30 day interval or would anything between 28-30 days be considered a monthly interval?
I was planning on doing 30 because it seems that's what customers would expect, but I'm also curious if some companies charge at a fixed interval other than 30 days.
Billing monthly is assumed to be 12 times per year, not once every thirty days.
Preferably, billing should be on the anniversary of the original billing date of the month. If the current month has fewer days than the original billing DOM, bill on the last day of the current month, but on the next month, bill again on the anniversary day.