Reputation: 95
I am a little stumped on this. I can get a number of hours or a total number of minutes, but I need both hours and minutes (if job took more than 60 minutes). Start time and end time (datetime datatype) are stored in fields in tuples in the database.
I need to get hours (if over 60 mins) and remaining minutes. I have the following calculations in my sql query. I know the giving me a total minutes, I just need to make any left over after removing hours.
If the start time is 11:15am and the end time is 12:25pm, I need 1 hour 10 minutes.
sqlQuery = "select distinct(job_#1) as 'Job Number', " +
"client_name as 'Client Name', " +
"Convert(varchar,min(date),101) as 'Start Date', " +
"convert(varchar, max(date), 101) as 'End Date', " +
"FORMAT(sum(datediff(mi, START_TIME,END_TIME)%(60*24)/60),'#','en-us' ) as 'Hours', " + // calculate the total time taken on the job - formatted numeric
"FORMAT(sum(datediff(mi, START_TIME,END_TIME)%(60*24)%60),'#','en-us' ) as 'Minutes', " + // calculate the total time taken on the job - formatted numeric
"FORMAT(sum((datediff(MINUTE,start_time,end_time))/60.00)*25.00, 'C', 'en-us') as 'Total Labor' " + // multiple the job time by a $$ per hour rate - formatted as currency
"from " + ssqltable + " " + // table from which data is pulled
"where job_#1 IS NOT NULL " + // find all jobs that have a job number leaving out blank job numbers
"and date>='" + myDate + "' " + // filled in when selected or passes null and shows all data
"group by job_#1, Client_Name " + // aggregate grouping
"order by job_#1;"; // column(s) to order the data
Here is an example of my output..
237452 AADC 05/18/2017 05/18/2017 1 **208** $111.67
237353 Wolverine 05/18/2017 05/18/2017 **110** $45.83
237492 Beeman 05/11/2017 05/16/2017 **74** $30.83
Upvotes: 1
Views: 1452
Reputation: 38063
You can use datediff()
with hour
for hours (if you were not summing), and minute
for minutes, and divide or modulo as needed:
select
[Job Number] = [job_#1]
, [Client Name]= client_name
, [Start Date] = convert(char(10),min(date),101)
, [End Date] = convert(char(10),max(date),101)
, Hours = sum(datediff(minute,Start_Time,End_Time))/60
, Minutes = sum(datediff(minute,Start_Time,End_Time))%60
, [Total Labor]= (sum(datediff(minute,Start_Time,End_Time))/60.00) * 25.00
from tbl
where job_#1 is not null
and [date] >= @date_parameter
group by [job_#1], client_name
order by [job_#1]
Notes:
varchar
without (length) - Aaron Bertrandformat()
performs pretty poorly: format()
is nice and all, but… - Aaron BertrandUpvotes: 2
Reputation: 13969
I think simple divide by 60 is enough as below:
sum( datediff(mi,START_TIME,END_TIME)/60 ) as [Hours]
sum( datediff(mi,START_TIME,END_TIME)%60 ) as [Minutes]
Format is not high performant. For your scenario you can avoid
Upvotes: 0
Reputation: 1842
The DIV (/) and MOD/Remainder (%) functions will do the trick if you have the Total Minutes.
DECLARE @TotalMinutes int
SET @TotalMinutes = 70
SELECT @TotalMinutes / 60 AS Hours,
@TotalMinutes % 60 AS Minutes
This returns the following results:
Total Minutes Hours Minutes
70 1 10
121 2 1
Upvotes: 1
Reputation: 17146
Your code should be like below. Please note the changes in the order of parenthesis for hours and minutes. First SUM all minutes and then divide or modulo by 60 (integer) to get hours and minutes.
sqlQuery = "select distinct(job_#1) as 'Job Number', " +
"client_name as 'Client Name', " +
"Convert(varchar,min(date),101) as 'Start Date', " +
"convert(varchar, max(date), 101) as 'End Date', " +
"FORMAT(sum(datediff(mi, START_TIME,END_TIME)/60),'#','en-us' ) as 'Hours', " + // calculate the total time taken on the job - formatted numeric
"FORMAT(sum(datediff(mi, START_TIME,END_TIME))%60),'#','en-us' ) as 'Minutes', " + // calculate the total time taken on the job - formatted numeric
"FORMAT(sum(datediff(MINUTE,start_time,end_time)/60.00)*25.00, 'C', 'en-us') as 'Total Labor' " + // multiple the job time by a $$ per hour rate - formatted as currency
"from " + ssqltable + " " + // table from which data is pulled
"where job_#1 IS NOT NULL " + // find all jobs that have a job number leaving out blank job numbers
"and date>='" + myDate + "' " + // filled in when selected or passes null and shows all data
"group by job_#1, Client_Name " + // aggregate grouping
"order by job_#1;"; // column(s) to order the data
Upvotes: 0