Showing only hours and minutes? - sql

How to display only hours and minutes in a field if I get them separately
[SELECT
D.numOperador,
SUM(DATEDIFF(MINUTE, D.FechaSalida, D.FechaLlegada)) / 60 AS \[Horas\] ,
SUM(DATEDIFF(MINUTE, D.FechaSalida, D.FechaLlegada)) % 60 AS \[Minutos\]
FROM
trkOperadores O
INNER JOIN trfDespacho D ON O.NumOperador = D.numOperador
WHERE
O.cveTipoOperador = 2
AND O.NumOperador = 900200
AND D.FechaSalida>='2017-03-10 00:00:00.000' AND D.FechaLlegada<='2017-03-11 00:00:00.000'
GROUP BY
D.NumOperador;
GO]
Time

If you just want to join hrs and mns together in the result, concatenate both of them :
SELECT
D.numOperador,
( cast ( SUM(DATEDIFF(MINUTE, D.FechaSalida, D.FechaLlegada)) / 60 as varchar)
+
cast ( SUM(DATEDIFF(MINUTE, D.FechaSalida, D.FechaLlegada)) % 60 AS varchar ) ) as time
FROM
trkOperadores O
INNER JOIN trfDespacho D ON O.NumOperador = D.numOperador
WHERE
O.cveTipoOperador = 2
AND O.NumOperador = 900200
AND D.FechaSalida>='2017-03-10 00:00:00.000' AND D.FechaLlegada<='2017-03-11 00:00:00.000'
GROUP BY
D.NumOperador;
GO]

I assume that you want something like this.
DECLARE #D1 DATETIME = '20170401'
DECLARE #D2 DATETIME = '20170402 00:05:00'
SELECT RIGHT( '00' + CAST(DATEDIFF(MINUTE, #D1, #D2) /60 AS VARCHAR(2)) , 2) + ':' + RIGHT( '00' + CAST(DATEDIFF(MINUTE, #D1, #D2) % 60 AS VARCHAR(2)) , 2)
-- 24:05

SELECT
D.numOperador,
SUM(DATEDIFF(MINUTE, D.FechaSalida, D.FechaLlegada)) / 60 AS [Horas] ,
SUM(DATEDIFF(MINUTE, D.FechaSalida, D.FechaLlegada)) % 60 AS [Minutos]
CONVERT(VARCHAR(10),CAST(CAST (D.FechaSalida AS FLOAT) - CAST (D.FechaLlegada AS FLOAT) / 86400. AS DATETIME),108) --86400 equal 1 day
FROM
trkOperadores O INNER JOIN trfDespacho D
ON O.NumOperador = D.numOperador
WHERE
O.cveTipoOperador = 2
AND O.NumOperador = 900200
AND D.FechaSalida>='2017-03-10 00:00:00.000' AND D.FechaLlegada<='2017-03-11 00:00:00.000'
GROUP BY
D.NumOperador;
GO

Related

Convert SUM of integer to HH:MM format

I have time stored in minutes in integer datatype which has to be displayed in HH:MM format. For example: if total minutes is 80 then it should convert to 01:20.
select SUM(OTTime) from dbo.TableOT where ....
I have tried some queries but didn't get the exact output.
Updated Query:
SELECT SUM(t.OTTime),d.combovalue
FROM dbo.employee e
join dbo.OT t
on e.id = t.employeeid
JOIN dbo.combovalues d
ON e.department = d.id
GROUP By d.combovalue
Try this Single Query:
DECLARE #Duration int
SET #Duration= 4000
SELECT CAST( CAST((#Duration) AS int) / 60 AS varchar) + ':' + right('0' + CAST(CAST((#Duration) AS int) % 60 AS varchar(2)),2)
For Updated Query:
SELECT d.combovalue,CAST(CAST((SUM(t.OTTime)) AS int) / 60 AS varchar) + ':'
+ right('0' + CAST(CAST((SUM(t.OTTime)) AS int) % 60 AS varchar(2)),2)
FROM dbo.employee e join dbo.OT t on e.id = t.employeeid
JOIN dbo.combovalues d ON e.department = d.id
GROUP By d.combovalue
Instead of #minutes variable you can use SUM(OTTime) and a from clause in this below Query
DECLARE #minutes INT=80
SELECT CASE WHEN #minutes >= 60 THEN (SELECT CAST((#minutes / 60) AS VARCHAR(2)) + ':' + CASE WHEN (#minutes % 60) > 0 THEN CAST((#minutes % 60) AS VARCHAR(2))
ELSE '' END)
ELSE CAST((#minutes % 60) AS VARCHAR(2)) END
For Eg:
SELECT CASE WHEN SUM(OTTime) >= 60 THEN (SELECT CAST((SUM(OTTime) / 60) AS VARCHAR(2)) + ':' + CASE WHEN (SUM(OTTime) % 60) > 0 THEN CAST((SUM(OTTime) % 60) AS VARCHAR(2))
ELSE '' END)
ELSE CAST((SUM(OTTime) % 60) AS VARCHAR(2)) END
from dbo.TableOT where ....
Create a SCALAR Function and pass the
select dbo.Minutes_to_HrsMts (SUM(OTTime)) from dbo.TableOT where ....
Function:
CREATE Function dbo.Minutes_to_HrsMts (#minutes INT)
RETURNS nvarchar(30)
AS
BEGIN
declare #hours nvarchar(20)
SET #hours =
CASE WHEN #minutes >= 60 THEN
(SELECT CAST((#minutes / 60) AS VARCHAR(2)) + ':' +
CASE WHEN (#minutes % 60) > 0 THEN
CAST((#minutes % 60) AS VARCHAR(2))
ELSE
''
END)
ELSE
CAST((#minutes % 60) AS VARCHAR(2))
END
return #hours
END
First, I recommend using decimal hours. Much simpler:
SELECT d.combovalue, SUM(t.OTTime) / 60.0
FROM dbo.employee e JOIN
dbo.OT t
ON e.id = t.employeeid JOIN
dbo.combovalues d
ON e.department = d.id
GROUP By d.combovalue;
But that is not your question. If you knew that there are never more than 24 hours, you could use the TIME data type:
CONVERT(VARCHAR(5), DATEADD(minute, SUM(t.OTTime), 0), 8)
If that is too dangerous, then you need to convert to a string:
CONCAT(FORMAT(SUM(t.OTTime) / 60, '00'), ':', FORMAT(SUM(t.OTTime) % 60, '00'))

Operand data type varchar is invalid for avg operator

I keep getting the above error message
"Operand data type varchar is invalid for avg operator"
Can anyone fix it for me? PLEASE
WITH Average -- Calculating Mean
AS (
SELECT avg(convert(VARCHAR(5), DateDiff(s, [ARRIVAL_DATE_TIME], [COMPLETE_DATE_TIME]) / 3600) + ':' + convert(VARCHAR(5), DateDiff(s, [ARRIVAL_DATE_TIME], [COMPLETE_DATE_TIME]) % 3600 / 60) + ':' + convert(VARCHAR(5), (DateDiff(s, [ARRIVAL_DATE_TIME], [COMPLETE_DATE_TIME]) % 60))) AS Average
FROM [CLERKS]
WHERE [ARRIVAL_DATE_TIME] >= DATEADD(dd, - 30, getdate() - 1)
)
,data
AS (
SELECT cast(ARRIVAL_DATE_TIME AS DATE) AS Attendance_Date
,avg(convert(VARCHAR(5), DateDiff(s, [ARRIVAL_DATE_TIME], [COMPLETE_DATE_TIME]) / 3600) + ':' + convert(VARCHAR(5), DateDiff(s, [ARRIVAL_DATE_TIME], [COMPLETE_DATE_TIME]) % 3600 / 60) + ':' + convert(VARCHAR(5), (DateDiff(s, [ARRIVAL_DATE_TIME], [COMPLETE_DATE_TIME]) % 60))) AS Arr_Com
FROM [Clerks]
WHERE [ARRIVAL_DATE_TIME] >= DATEADD(dd, - 30, getdate() - 1)
GROUP BY cast(ARRIVAL_DATE_TIME AS DATE)
)
SELECT a.Attendance_Date
,a.Arr_Com
,c.Average
,abs(a.Arr_Com - b.Arr_Com) AS MR
FROM data a
LEFT JOIN data b ON cast(a.Attendance_Date AS DATETIME) = cast(b.Attendance_Date AS DATETIME) + 1
CROSS JOIN Average c
ORDER BY a.Attendance_Date
GO
Thanks in Advance
Actually, the problem is that the implementation is incorrect. You don't want to average timestamps (5h:3m:20s), but durations.
Hence, you need to calculate the duration in the smallest denominator, in your case seconds, calculate the average in seconds, by using the AVG() function and then formatting that result to look like hh:mm:ss.
Your code should look like:
;WITH Average -- Calculating Mean
AS (
SELECT AVG(DateDiff(s, [ARRIVAL_DATE_TIME], [COMPLETE_DATE_TIME])) as Average
FROM [CLERKS]
WHERE [ARRIVAL_DATE_TIME] >= DATEADD(dd, - 30, getdate() - 1)
)
,data
AS (
SELECT cast(ARRIVAL_DATE_TIME AS DATE) AS Attendance_Date
, AVG(DateDiff(s, [ARRIVAL_DATE_TIME], [COMPLETE_DATE_TIME])) as Arr_Com
FROM [Clerks]
WHERE [ARRIVAL_DATE_TIME] >= DATEADD(dd, - 30, getdate() - 1)
GROUP BY cast(ARRIVAL_DATE_TIME AS DATE)
)
SELECT
Attendance_Date
, Arr_Com
, Average
, avg(convert(VARCHAR(5), MR / 3600) + ':' + convert(VARCHAR(5), MR % 3600 / 60) + ':' + convert(VARCHAR(5), MR % 60))) AS MR
FROM (
SELECT a.Attendance_Date
,a.Arr_Com
,c.Average
, abs(a.Arr_Com - b.Arr_Com) AS MR
FROM data a
LEFT JOIN data b ON cast(a.Attendance_Date AS DATETIME) = cast(b.Attendance_Date AS DATETIME) + 1
CROSS JOIN Average c
) tmp
ORDER BY Attendance_Date

How to Find Time difference with hours, minutes and seconds (All Results) in SQL Server

How to Find Time difference with all conditions like
if difference only minutes
49 mintus
if a difference in Hour
1 hour 20 minutes
i am trying
SELECT DATEDIFF(MINUTE,'2018-08-09 10:16:49.000','2018-08-09 11:14:40.000') AS Diff
but this is only show in minutes
I have also tried this one
DECLARE #StartTime datetime = '2018-08-09 10:16:49.000',
#EndTime datetime = '2018-08-09 12:44:05.000'
SELECT CAST(#EndTime - #StartTime as Time) As TimeDiffere
output : 02:27:16.0000000
but I want to 2hr 27mins 16Sec
If your SQL-server version higher than 2012, you can try to sue format function.
CREATE TABLE T(
StartTime datetime,
EndTime datetime
);
insert into t values ('2018-08-09 10:16:49.000','2018-08-09 12:44:05.000')
Query 1:
SELECT format(EndTime - StartTime ,'hh\hr mm\min\s ss\Sec') As TimeDiffere
FROM T
Results:
| TimeDiffere |
|-------------------|
| 02hr 27mins 16Sec |
NOTE
Backslash \ can escape keyword from the format like hr,min,s..., then display it as the original word.
DECLARE #StartTime datetime = '2018-08-09 10:01:15.000',
#EndTime datetime = '2018-08-09 12:50:00.000'
SELECT CONCAT((DATEDIFF(second,#StartTime,#EndTime )/60)/60,'hr ',(DATEDIFF(second,#StartTime,#EndTime)/60)%60,'mins ',DATEDIFF(second,#StartTime,#EndTime)%60,'Sec')
As TimeDiffere
DECLARE #StartTime datetime = '2018-08-09 12:16:49.000',
#EndTime datetime = '2018-08-09 12:44:05.000'
select [hour] + [minute] + [second] as TimeDiffere
from (
select diff_sec = datediff(second, #StartTime, #EndTime)
) t
cross apply
(
select [hour] = isnull(convert(varchar(10), nullif(diff_sec / 60 / 60, 0))
+ ' hours ', '')
) hr
cross apply
(
select [minute] = isnull(convert(varchar(10), nullif(diff_sec / 60 % 60, 0))
+ ' mintues ', '')
) mn
cross apply
(
select [second] = isnull(convert(varchar(10), nullif(diff_sec % 60, 0))
+ ' seconds', '')
) sc
/* RESULT
27 mintues 16 seconds
*/
If you have a poor datetime functionality to get hh.mm.ss, then you can use apply :
select t.*, concat( (dtdiff / 3600), 'hr ', (dtdiff / 60) % 60, 'mins ', dtdiff % 60, 'sec')
from table t cross apply
( values (datediff(second, startdate, enddate))
) tt(dtdiff);

SUM of elapsed time gathered from multiple rows

I am trying to show my team's productivity vs non-productivity percentages based of what type of work they perform throughout the day. I can successfully achieve the format i am looking for with the below code but if an associate is productive in 2 separate departments in 1 day the sub-query fails because it returns multiple rows.
This is what im working with now
DECLARE
#Offset INT ,
#Start DATETIME ,
#Loc INT ,
#NON time(0) ,
#PROD time(0) ,
#TOTAL TIME(0)
SET #Offset = 4
SET #Start = dateadd(day, datediff(day, 0, getdate()), -#Offset)
--SUM OF ALL DEPT CATEGORIES WORKED FOR SELECTED DATE RANGE
select Codes = (DeptCode + ' ' + Opcode)
, TimeSum = right(convert(varchar(9),(sum(datediff(second,StartTime,FinishTime)) / 3600 )),3) + ':' + right('0' + convert(varchar(2),(sum(datediff(second,StartTime,FinishTime)) / 60) % 60 ),2)
, Units = sum(units)
FROM TimeLogNEW
where EventDate = #Start and Location = 10 and ID = 2372013
group by EventDate, id, DeptCode, OpCode
--SUM OF NON PRODUCTIVE HOURS WORKED (HAVING A UNITS SUM OF '0' IS CONSIDERED NON PRODUCTIVE) --NOT INCLUDING 'LL' (WHICH IS A LUNCH PERIOD)
set #NON =
(select NonProd = right(convert(varchar(9),(sum(datediff(second,'0:00:00',TimeSum)) / 3600 )),3) + ':' + right('0' + convert(varchar(2),(sum(datediff(second,'0:00:00',TimeSum)) / 60) % 60 ),2)
from (select
TimeSum = right(convert(varchar(9),(sum(datediff(second,m.StartTime,m.FinishTime)) / 3600 )),3) + ':' + right('0' + convert(varchar(2),(sum(datediff(second,m.StartTime,m.FinishTime)) / 60) % 60 ),2)
,Units = sum(m.units)
FROM TimeLogNEW m
where m.EventDate = #Start and opCode Not in ('ll') and m.Location = 10 and m.ID = 2372013
group by m.EventDate, m.id, m.DeptCode, m.OpCode
)t Group By Units Having Units = 0)
select #NON as 'NON-PROD_Hours'
--SUM OF PRODUCTIVE HOURS WORKED (HAVING A UNITS SUM OF MORE THAN '0' IS CONSIDERED PRODUCTIVE) --NOT INCLUDING 'LL' (WHICH IS A LUNCH PERIOD)
set #PROD =
(select TotalProd = right(convert(varchar(9),(sum(datediff(second,'0:00:00',TimeSum)) / 3600 )),3) + ':' + right('0' + convert(varchar(2),(sum(datediff(second,'0:00:00',TimeSum)) / 60) % 60 ),2)
from (select
TimeSum = right(convert(varchar(9),(sum(datediff(second,m.StartTime,m.FinishTime)) / 3600 )),3) + ':' + right('0' + convert(varchar(2),(sum(datediff(second,m.StartTime,m.FinishTime)) / 60) % 60 ),2)
,Units = sum(m.units)
FROM TimeLogNEW m
where m.EventDate = #Start and opCode Not in ('ll') and m.Location = 10 and m.ID = 2372013
group by m.EventDate, m.id, m.DeptCode, m.OpCode
)t Group By Units Having Units >0 )
select #PROD as 'PROD_Hours'
--SUM OF ALL HOURS WORKED --NOT INCLUDING 'LL' (WHICH IS A LUNCH PERIOD)
set #TOTAL =
(select
TotalTime_NoLunch = right(convert(varchar(9),(sum(datediff(second,StartTime,FinishTime)) / 3600 )),3) + ':' + right('0' + convert(varchar(2),(sum(datediff(second,StartTime,FinishTime)) / 60) % 60 ),2)
FROM TimeLogNEW
where EventDate = #Start and ID = 2372013 and OpCode not in ('ll'))
select #TOTAL as 'SUM_Hours'
--PERCENTAGE OF PRODUCTIVITY
select
[Prod%] =convert(varchar(30),(100 *datediff(minute,'0:00:00',#PROD)/datediff(minute,'0:00:00',#TOTAL) )) +'%'
--PERCENTAGE OF NON-PRODUCTIVITY
select
[NON Prod%] =convert(varchar(30),(100 *datediff(minute,'0:00:00',#NON)/datediff(minute,'0:00:00',#TOTAL) )) +'%'
Result shown. For 7-2-18
If more than 1 of the dept categories codes has greater than 0 Units the sub-query fails. I have been trying to re-arrange the query to allow the grouping of sums equaling 0 and sums having greater than 0, but am stumped here. I am not getting correct results when ungrouping the Units column in the sub.
Here is what the raw data looks like with more than 1 productive operation. 7-3-18
The problem is that you group by DeptCode and OpCode but do not sum these results over the groups. Try this:
DECLARE
#Offset INT ,
#Start DATETIME ,
#Loc INT = 10 ,
#NON INT ,
#PROD INT ,
#TOTAL INT
SET #Offset = 4;
SET #Start = DATEADD(day, DATEDIFF(day, 0, GETDATE()), -#Offset);
--SUM OF ALL DEPT CATEGORIES WORKED FOR SELECTED DATE RANGE
WITH
TimeLog (EventDate, [Location], ID, DeptCode, OpCode, Units, Seconds) AS (
SELECT EventDate, [Location], ID, DeptCode, OpCode, SUM(Units)
, SUM(DATEDIFF(second, StartTime, FinishTime))
FROM TimeLogNEW
GROUP BY EventDate, [Location], ID, DeptCode, OpCode
)
SELECT
Codes = (DeptCode + ' ' + Opcode)
, TimeSum = CAST(DATEADD(second, Seconds, 0) AS time(0))
, Units
FROM TimeLog
WHERE EventDate = #Start AND [Location] = #Loc AND ID = 2372013;
WITH
TimeLog (EventDate, [Location], ID, DeptCode, OpCode, Units, Seconds) AS (
SELECT EventDate, [Location], ID, DeptCode, OpCode, SUM(Units)
, SUM(DATEDIFF(second, StartTime, FinishTime))
FROM TimeLogNEW
GROUP BY EventDate, [Location], ID, DeptCode, OpCode
),
TimeSplit (EventDate, Loc, ID, DC, OC, Units, Seconds, NON_PROD, PROD) AS (
SELECT EventDate, [Location], ID, DeptCode, OpCode, Units, Seconds
, CASE WHEN Units = 0 THEN Seconds ELSE 0 END
, CASE WHEN Units > 0 THEN Seconds ELSE 0 END
FROM TimeLog
)
SELECT #NON = SUM(NON_PROD), #PROD = SUM(PROD), #TOTAL = SUM(Seconds)
FROM TimeSplit
WHERE EventDate = #Start AND Loc = #Loc AND ID = 2372013 AND OC NOT IN ('LL');
-- RESULTS
SELECT
CONVERT(nvarchar(30), #NON/3600) + RIGHT(CONVERT(nvarchar(8), DATEADD(second, #NON, 0), 108), 6) AS 'NON-PROD_Hours',
CONVERT(nvarchar(30), #PROD/3600) + RIGHT(CONVERT(nvarchar(8), DATEADD(second, #PROD, 0), 108), 6) AS 'PROD_Hours',
CONVERT(nvarchar(30), #TOTAL/3600) + RIGHT(CONVERT(nvarchar(8), DATEADD(second, #TOTAL, 0), 108), 6) AS 'SUM_Hours',
CAST(100.0 * #PROD / #TOTAL AS varchar(30)) +'%' AS 'Prod%',
CAST(100.0 * #NON / #TOTAL AS varchar(30)) +'%' AS 'NON Prod%';

Incorrect syntax near ';' sql

I have a query for my stored procedure I am working on displayed below. I have an incorrect syntax near ';" which is at the very end of my query. Still pretty new to T-sql and can't figure out why I am receiving this error. I have a feeling it has something to do with the sub queries I have but i'm not sure. How can I change this to allow execution?
Declare #startTime DateTime
Declare #endTime DateTime
SET #startTime = '2014-03-28 8:00:00';
SET #endTime = '2014-03-28 17:00:00';
SELECT sum(datepart(hour, HoursRan) * 3600 + datepart(minute, HoursRan) * 60 + datepart(second, HoursRan)) as TotalHoursRan, sum(datepart(hour, DownTime) * 3600 + datepart(minute, DownTime) * 60 + datepart(second, DownTime)) as TotalDownTime, (TotalDownTime / HoursRan) as PercentDown
from (select cast(#endTime - #startTime as time) AS HoursRan
from (select cast(max(DateAndTime) - min(DateAndTime) as time) as DownTime
from (select pt.*,
sum(case when datediff(second, prevdt, DateAndTime) <= 1 then 0 else 1 end) over
(order by DateAndTime) as grp
from (select pt.*, lag(DateAndTime) over (order by DateAndTime) as prevdt
from IncomingProductTracker pt
where Line4AFaultStatus = 1 and
DateAndTime > '2014-03-28 8:00:00' and
DateAndTime < '2014-03-28 17:00:00'
) pt
) pt
group by grp) pt;
As others have said, you can use a different alias to make finding errors like this easier. In this case, you were missing a name for one of your sub-queries.
DECLARE #startTime DATETIME
DECLARE #endTime DATETIME
SET #startTime = '2014-03-28 8:00:00';
SET #endTime = '2014-03-28 17:00:00';
SELECT SUM(DATEPART(hour, HoursRan) * 3600 + DATEPART(minute, HoursRan) * 60
+ DATEPART(second, HoursRan)) AS TotalHoursRan
, SUM(DATEPART(hour, DownTime) * 3600 + DATEPART(minute, DownTime) * 60
+ DATEPART(second, DownTime)) AS TotalDownTime
, ( TotalDownTime / HoursRan ) AS PercentDown
FROM ( SELECT CAST(#endTime - #startTime AS TIME) AS HoursRan
FROM ( SELECT CAST(MAX(DateAndTime) - MIN(DateAndTime) AS TIME) AS DownTime
FROM ( SELECT pt.*
, SUM(CASE WHEN DATEDIFF(second,
prevdt,
DateAndTime) <= 1
THEN 0
ELSE 1
END) OVER ( ORDER BY DateAndTime ) AS grp
FROM ( SELECT pt.*
, lag(DateAndTime) OVER ( ORDER BY DateAndTime ) AS prevdt
FROM IncomingProductTracker pt
WHERE Line4AFaultStatus = 1
AND DateAndTime > '2014-03-28 8:00:00'
AND DateAndTime < '2014-03-28 17:00:00'
) pt
) pt
GROUP BY grp
) pt
) pt;
Using different aliases:
DECLARE #startTime DATETIME
DECLARE #endTime DATETIME
SET #startTime = '2014-03-28 8:00:00';
SET #endTime = '2014-03-28 17:00:00';
SELECT SUM(DATEPART(hour, HoursRan) * 3600 + DATEPART(minute, HoursRan) * 60
+ DATEPART(second, HoursRan)) AS TotalHoursRan
, SUM(DATEPART(hour, DownTime) * 3600 + DATEPART(minute, DownTime) * 60
+ DATEPART(second, DownTime)) AS TotalDownTime
, ( TotalDownTime / HoursRan ) AS PercentDown
FROM ( SELECT CAST(MAX(DateAndTime) - MIN(DateAndTime) AS TIME) AS DownTime
, CAST(#endTime - #startTime AS TIME) AS HoursRan
FROM ( SELECT a.*
, SUM(CASE WHEN DATEDIFF(second, prevdt,
DateAndTime) <= 1
THEN 0
ELSE 1
END) OVER ( ORDER BY DateAndTime ) AS grp
FROM ( SELECT pt.*
, lag(DateAndTime) OVER ( ORDER BY DateAndTime ) AS prevdt
FROM IncomingProductTracker pt
WHERE Line4AFaultStatus = 1
AND DateAndTime > '2014-03-28 8:00:00'
AND DateAndTime < '2014-03-28 17:00:00'
) a
) b
GROUP BY grp
) c;
I believe declare statements should be ended with semi-colons.
http://technet.microsoft.com/en-us/library/ms188927.aspx