MS- Access query for total hours and time deduction - sql

I need to perform a time sheet calculations Employee will punch in and punch out. I store those records in one table. That table has time and a field for in punch or out punch. Employee may go out for lunch or other reasons and punches for out and in. I need to deduct those times and get the working hours. My table will look like below :
PunchTime EmpCode IsInpunch
10:01 AM (A) T
12:03 PM (A) F (this isoutpunch)
01:05 PM (A) T
07:14 PM (A) F
10:32 AM (B) T
For (A)'s time 7.14 - 10.01 is the total hours, but he was not there between 12.03 to 01.05 so I need to deduct the lunch time and get the total hours. How to do this in Query

This is pretty straightforward. Assuming your T and F IsInPunch is balanced, which is to say for any day, you will have T-F or T-F-T-F etc (always paired), just total up the F and subtract the total of T's.
select empcode, DateValue(PunchTime),
sum(IIF(IsInPunch='F',PunchTime,0)) -
sum(IIF(IsInPunch='T',PunchTime,0))
from TimeSheet
group by empcode, DateValue(PunchTime)
(haven't got Access open but do check the syntax)

Related

Date_diff with specific condition time start and time end

is it possible to have date_diff with specific start and end time?
let say my store are open from 8AM - 10PM, which is 14 Hours.
and I have a lot of stuff to sell during that time. One of the SKU is out of stock from 2022-11-01 06.00 PM until tomorrow 2022-11-02 11.00 AM.
Instead of calculate 24 hours, I just want to calculate only from opening store until it closed or until its restock. Meaning from 6PM to 11AM is 8 Hours
my query
select date_diff('2022-11-02 11.00 AM', '2022-11-02 06.00 PM', hour) from table
with the result 17 hours instead of 8 hours
There isn't a way to configure DATE_DIFF to do this for you, but it's possible to do what you want, with some effort.
You should convert your dates to timestamps (TIMESTAMP(yourdate) or CAST(yourdate AS TIMESTAMP)) and use TIMESTAMP_DIFF instead.
This will allow you to work with smaller intervals than days.
For your calculation, you ultimately need to find the total time difference between the two timestamps and then subtract the out-of-hours timeframe.
However, calculating the latter is not as simple as taking the difference in days and multiplying by 8 hours (10pm-6am), because your out-of-hours calculation has to account for weekends and possibly holidays etc. Hence it can get quite complex, which is where the solution in my first link might come in.

how to write a sql to calculate working hours minus rest time

I have a table of rest time in work shift
Begin end
12:00 12:30
17:30 18:30
Now I want to write a SQL to calculate actual working hours given the start and end time. For example if start at 9:00 and end at 15:00, the actual hours is 6-rest time=5.5 hours and if start at 9:00 and end at 20:00 the actual hours is 10 hours. How to write a procedure to check it in SQL server? Thx.
There are no schema details to work with here, which means the following SQL is generic and will have to be altered to fit your db.
SELECT
(datediff(minute, shiftStartTime, shiftEndTime)
- datediff(minute,breakStartTime,breakEndTime)) / 60.0
FROM yourTable
Notes:
If they can have multiple breaks, you need to sum up all the break times in minutes before deducting it from the shift period.
the calculation is specifically in minutes because the datediff counts the number of boundaries passed, so the date diff in hours between 11:59 and 12:01 is 1, even though the break is 2 minutes, you would count that as 1 hour if you count hours using the function.
If you can provide more schema details, we would be able to craft a more complete statement.
you can try below way using DATEDIFF
select *, CONVERT(time(7),DATEADD(s, DATEDIFF(s,S,E),'00:00:00')) from QQ
http://sqlfiddle.com/#!18/01213d/1
for your case column name will be
select *, CONVERT(time(7),DATEADD(s, DATEDIFF(s,Begin,end),'00:00:00')) from yourtable

Cumulative count in SQL

I am working on SQL and came across one scenario that needs to build in SQL.
Below is scenario:
PatientID AdmitDate DischargeDate
12 7/24/2017 09:45 7/24/2017 11:01
13 7/21/2016 08:37 7/22/2017 00:15
I want result set as below:
For patientID 13, count is calculated in first 2 rows and
For patientid 12, count is calculated in last row.
Well, that looks like whatever you do will be slow. I think I'd use a tally table. The table, instead of just containing the usual n years worth of dates / days / day of week etc. would also contain one record for each hour in the day. The Primary Key would represent one of those segments.
Then you could pass the admission date and discharge date for a patient to a function that would return a list, or range, of the hours that the patient is in for. So, Patient 13 might get a return value of (for example) 1500,1517 (i.e the patient was in for 17 hours and you will know the date and time because 1500 will be the Primary Key of a record that gives you the date and hour of the day he was admitted). Patient 12 would (to continue the example) return a value of 1544,1546
You could then build the dataset from Date A to Date B by returning all the data between those dates from the tally table and then check whether each hour is a yes or no for a particular patient.
The display of the data - your desired result set - I would do in somewhere else. I'd probably return two datasets. One would be used to build your table structure. The other would be used to decide whether to put a '1' in the box or not. You could do your summing on the fly.
I imagine this would get interesting with patients on the same dates ... you'd have to show each patient separately?

Calculate the working hours between two dates in sql server excluding weekend

I am working on a rent system database where a car is given on rent. I need to calculate the (sum of time difference) total time of loan for a car in the given date time range for only working hours and excluding weekend.
Examples to clarify the scenarios
our given date range in where clause is 1/02/17 and 5/2/17
Joe books a car on 01/02/2017 at 9am and returns it at 5pm on 01/02/2017 … 8 hour booking included.
our given date range in where clause is 19/02/17 and 20/2/17
Trish books car on 19/02/2017 at 9am and returns it at 5pm on 21/02/2017 … 16 hour booking included only (ie. 19th & 20th), as the 3rd day falls outside our Date Range end point of 20/02/2017.
our given date range in where clause is 1/02/17 and 5/2/17
Tom books car on 31/01/2017 at 9am and returns it at 12pm on 01/02/2017 … 3 hour booking included only (ie. ½ day on 1st Feb), as the the 1st day (ie. 31st Jan) falls outside our Date Range starting point of 01/02/2017
If any of the column values differ (ie. Company Name, Loan Vehicle Registration, Service Advisor, or Drivers Number Plate)then, that will be a unique row. But if those column are all the same and the only difference is the booking date (ie. if Joe books same car out twice within the Date Range period, using the same Company, Service Advisor, and Drivers Number Plate), then that should be grouped/calculated as one record line.
My current stored procedure is
ALTER PROCEDURE [dbo].[bookingAnalysis]
#from_date nvarchar(50)=NULL,
#to_date nvarchar(50)=NULL
AS
BEGIN
SET NOCOUNT ON;
Select cmp.CompanyName,v.NumberPlate as Loan_Vehicle_Registration,m.ModelDescription as Vehicle_Description,
cnt.FirstName,cnt.LastName,DATEDIFF(HOUR,b.DueOutDate,b.ActualReturnedDate)as
Duration_of_Loan,b.bookingID,b.DriversNumberPlate from Bookings as b
inner join Companies as cmp on b.AssignedCompanyID=cmp.CompanyID
inner join Vehicles as v on v.VehicleID=b.VehicleID
inner join Models as m on m.ModelID=v.ModelID inner join Contacts
cnt on cnt.ContactID=b.ContactID where b.DueOutDate>= #from_date and b.ActualReturnedDate<= #to_date
END
Currently I am getting datediff between b.DueoutDate and b.ActualReturnDate
It's going to be a lot simpler to do this if you first create a calendar table, with one row per date. You can use that then to filter out weekends, and you will get one row as a result for each of the days when the booking is valid.
After that you just have to check:
if the start date is the same as calendar date -> check possible hours to be deducted from the start
if the end date is the same as calendar date -> check possible hours to be deducted from the end
Then just sum all other days with 8 hours, if that was your working day.

Query to find a block of time in a schedule

Imagine I had a work schedule from 9am to 6pm. It is divided into 15 minute blocks and appointments (increments of 15 minutes) can be fitted into the times available.
Now, if I need to insert a new appointment that is 45 minutes long is there an easy query to find a block of time that is available to fit the appointment in for a given date
The basic table design is
AppointmentId
Date
StartTime
Length - 15 minute incremenents
I would like to get a list of available times to choose from, so if the only appointment for the given day is a 30 minute one at 9:30 then the list of times would be
(No times before 9:30 as the 45 minute appointment wont fit)
10:15
10:30
10:45
...
5:15pm (last time of the day the appointment will fit)
By using ranking function (i.e Row_Number()) set number for each row in each day (let say it's name is rn), then join this query with it self by this condition q2.rn = q1.rn-1 then you have end of appointment beside start of next appointment, then calculate datediff(mi) on this end and start, so this value is the gap, then write another query wrapping this query to filter records that have gap >= yourNeededTime. Also for start of day and end of day you can create 2 dummy records one for 9am and one for 6pm so that yo can handle gap of start of day to the first appointment and last appointment to the end of day.
I hope this helps