how to get sum() from alise column in SQL - sql

I'd like the sum of TotalVisitedTime time but it is alias column so how can I gtt it?
Select CONVERT(varchar(6), DATEDIFF(second, [Start], [End])/3600)
+ ':'
+ RIGHT('0' + CONVERT(varchar(2), (DATEDIFF(second, [Start], [End]) % 3600) / 60), 2)
+ ':'
+ RIGHT('0' + CONVERT(varchar(2), DATEDIFF(second, [Start], [End]) % 60), 2) AS TotalVisitedTime
FROM [Table Name]
Note: [Start] and [End] are columns name.

SELECT SUM(TotalVisitedTime)
FROM (
-- AS PER #Alex Aza, #Andriy M
SELECT 1234 AS TotalVisitedTime
) AS OuterTable

I think it makes sense to sum up seconds and then do the conversion you are trying to do.
SELECT CONVERT(varchar(6), diff/3600)
+ ':'
+ RIGHT('0' + CONVERT(varchar(2), (diff % 3600) / 60), 2)
+ ':'
+ RIGHT('0' + CONVERT(varchar(2), diff % 60), 2) AS TotalVisitedTime
FROM
(
select sum(DATEDIFF(second, [Start], [End]) diff
from [Table Name]
) tt

Related

How i can remove results of my Query, using LAG function?

First of all, srry for my bad english.
I need to calculate the iddle time of an separators group. Actualy i have the following query:
USE mydatabase
SELECT p.iddoc as SaleOrder, p.name as Client, u.username as SysUser,
CONVERT(DATETIME, o.creatdate) as CreateDate,
CONVERT(DATETIME, o.inidate) as IniDate,
CONVERT(DATETIME, o.findate) as FinalDate,
RIGHT('0' + CAST(DATEDIFF(S, (lag(o.findate, 1) OVER (ORDER BY o.findate)), o.inidate) / 3600 AS VARCHAR(2)),2) + ':'
+ RIGHT('0' + CAST(DATEDIFF(S, (lag(o.findate, 1) OVER (ORDER BY o.findate)), o.inidate) % 3600/60 AS VARCHAR(2)),2) + ':'
+ RIGHT('0' + CAST(DATEDIFF(S, (lag(o.findate, 1) OVER (ORDER BY o.findate)), o.inidate) % 60 AS VARCHAR(2)),2) as IdleTime
FROM serviceorder o
inner join user u on o.usercode = u.codusuario
inner join requests p on o.idrequest = p.codpedidocab
WHERE u.username like ('USER NAME')
and o.iduserstart is NOT NULL
and p.sit = '8'
and o.creatdate BETWEEN '2020-06-30 00:00:00' and '2020-06-30 23:59:00'
and o.inidate BETWEEN '2020-06-30 00:00:00' and '2020-06-30 23:59:00'
ORDER BY o.inidate
My problem on this query is when "o.inidate is < than a last o.findate", i need to remove the results than have "o.inidate < (lag(o.findate, 1) OVER (ORDER BY o.findate))", but i can't this because can't use the LAG on the where.
What do you suggest i do?
Window functions can be used in the select and order by clauses only. You can use a subquery instead:
SELECT *
FROM (
SELECT
p.iddoc as SaleOrder,
p.name as Client,
u.username as SysUser,
CONVERT(DATETIME, o.creatdate) as CreateDate,
CONVERT(DATETIME, o.inidate) as IniDate,
CONVERT(DATETIME, o.findate) as FinalDate,
LAG(o.findate) OVER (ORDER BY o.findate) lagFinalDate,
RIGHT('0' + CAST(DATEDIFF(S, (lag(o.findate, 1) OVER (ORDER BY o.findate)), o.inidate) / 3600 AS VARCHAR(2)),2) + ':'
+ RIGHT('0' + CAST(DATEDIFF(S, (lag(o.findate, 1) OVER (ORDER BY o.findate)), o.inidate) % 3600/60 AS VARCHAR(2)),2) + ':'
+ RIGHT('0' + CAST(DATEDIFF(S, (lag(o.findate, 1) OVER (ORDER BY o.findate)), o.inidate) % 60 AS VARCHAR(2)),2) as IdleTime
FROM serviceorder o
INNER JOIN [user] u ON o.usercode = u.codusuario
INNER JOIN requests p ON o.idrequest = p.codpedidocab
WHERE
u.username = 'USER NAME'
AND o.iduserstart is NOT NULL
AND p.sit = '8'
AND o.creatdate >= '2020-06-30'
AND o.creatdate < '2020-07-01'
AND o.inidate >= '2020-06-30'
AND o.inidate < '2020-07-01'
) t
where IniDate < lagFinalDate
Additional changes to the query:
half-open interval filters are more accurate (and easier to understand) than between
u.username like ('USER NAME') is equivalent to u.username = 'USER NAME'
user is a language keyword, hence it needs to be quoted when used as a table name

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 can i sum all the overtime duration

I can't figure out how to sum all the over time duration from the query.
I have to sum it using another query...
This is the query I made to get the over time duration and the other time duration...
Select empId, firstTimeIn, firstTimeOut, secondTimeIn, secondTimeOut, overTimeIn, overTimeOut, attendanceDate,
(RIGHT('0' + CAST(DATEDIFF(second, Convert (time, firstTimeIn), Convert (time, firstTimeOut) ) / 3600 AS VARCHAR(2)), 2) + ':'
+ RIGHT('0' + CAST(DATEDIFF(second, Convert (time, firstTimeIn), Convert (time, firstTimeOut) ) % 3600 / 60 AS VARCHAR(2)), 2) + ':'
+ RIGHT('0' + CAST(DATEDIFF(second, Convert (time, firstTimeIn), Convert (time, firstTimeOut) ) % 3600 % 60 AS VARCHAR(2)), 2) ) as FirstTime
,
(RIGHT('0' + CAST(DATEDIFF(second, Convert (time, secondTimeIn), Convert (time, secondTimeOut) ) / 3600 AS VARCHAR(2)), 2) + ':'
+ RIGHT('0' + CAST(DATEDIFF(second, Convert (time, secondTimeIn), Convert (time, secondTimeOut) ) % 3600 / 60 AS VARCHAR(2)), 2) + ':'
+ RIGHT('0' + CAST(DATEDIFF(second, Convert (time, secondTimeIn), Convert (time, secondTimeOut) ) % 3600 % 60 AS VARCHAR(2)), 2)) as SecondTime
,
(RIGHT('0' + CAST(DATEDIFF(second, Convert (time, overTimeIn), Convert (time, overTimeOut) ) / 3600 AS VARCHAR(2)), 2) + ':'
+ RIGHT('0' + CAST(DATEDIFF(second, Convert (time, overTimeIn), Convert (time, overTimeOut) ) % 3600 / 60 AS VARCHAR(2)), 2) + ':'
+ RIGHT('0' + CAST(DATEDIFF(second, Convert (time, overTimeIn), Convert (time, overTimeOut) ) % 3600 % 60 AS VARCHAR(2)), 2)) as OverTimeDuration
from tbl_EmployeeAttendance Where attendanceDate BETWEEN '2019-09-01' AND '2019-09-15' And empId = '41' AND
((RIGHT('0' + CAST(DATEDIFF(second, Convert (time, firstTimeIn), Convert (time, firstTimeOut) ) / 3600 AS VARCHAR(2)), 2) + ':'
+ RIGHT('0' + CAST(DATEDIFF(second, Convert (time, firstTimeIn), Convert (time, firstTimeOut) ) % 3600 / 60 AS VARCHAR(2)), 2) + ':'
+ RIGHT('0' + CAST(DATEDIFF(second, Convert (time, firstTimeIn), Convert (time, firstTimeOut) ) % 3600 % 60 AS VARCHAR(2)), 2) ) >= '04:00:00') AND
((RIGHT('0' + CAST(DATEDIFF(second, Convert (time, secondTimeIn), Convert (time, secondTimeOut) ) / 3600 AS VARCHAR(2)), 2) + ':'
+ RIGHT('0' + CAST(DATEDIFF(second, Convert (time, secondTimeIn), Convert (time, secondTimeOut) ) % 3600 / 60 AS VARCHAR(2)), 2) + ':'
+ RIGHT('0' + CAST(DATEDIFF(second, Convert (time, secondTimeIn), Convert (time, secondTimeOut) ) % 3600 % 60 AS VARCHAR(2)), 2)) >= '04:00:00')
Try this code to add the table and its value....
CREATE TABLE tbl_EmployeeAttendance (
empId int,
firstTimeIn time,
firstTimeOut time,
secondTimeIn time,
secondTimeOut time,
overTimeIn time,
overTimeOut time,
attendanceDate varchar(100)
)
Insert into tbl_EmployeeAttendance VALUES ('41','07:30:00','12:10:00','12:55:00','17:20:00','17:45:00','19:30:02','2019-09-02')
Insert into tbl_EmployeeAttendance VALUES ('41','07:24:00','12:12:00','12:55:00','17:20:00','','','2019-09-03')
Insert into tbl_EmployeeAttendance VALUES ('41','07:23:00','12:10:00','12:55:00','17:20:00','','','2019-09-04')
Insert into tbl_EmployeeAttendance VALUES ('41','07:30:00','12:10:00','12:55:00','17:20:00','','','2019-09-05')
Insert into tbl_EmployeeAttendance VALUES ('41','07:24:00','12:12:00','12:55:00','17:20:00','','','2019-09-06')
Insert into tbl_EmployeeAttendance VALUES ('41','07:05:00','12:09:00','12:55:00','17:20:00','17:45:00','19:30:02','2019-09-09')
Insert into tbl_EmployeeAttendance VALUES ('41','07:05:00','12:09:00','12:55:00','17:20:00','','','2019-09-10')
Insert into tbl_EmployeeAttendance VALUES ('41','07:05:00','12:09:00','12:55:00','17:20:00','','','2019-09-11')
Insert into tbl_EmployeeAttendance VALUES ('41','07:30:00','12:09:00','12:55:00','17:20:00','','','2019-09-12')
Insert into tbl_EmployeeAttendance VALUES ('41','07:30:00','12:10:00','12:55:00','17:20:00','17:45:00','19:30:02','2019-09-13')
Use DATEDIFF(interval,date1,date2) If you work with MSSQL
SELECT empId, convert(varchar(5),totalFirstTiomeInHoure/3600)+':'+convert(varchar(5),totalFirstTiomeInHoure%3600/60)+':'+convert(varchar(5),(totalFirstTiomeInHoure%60)) as FirstTime,
convert(varchar(5),totalSecondTiomeInHoure/3600)+':'+convert(varchar(5),totalSecondTiomeInHoure%3600/60)+':'+convert(varchar(5),(totalSecondTiomeInHoure%60)) as SecondTime,
convert(varchar(5),totalOverTiomeInHoure/3600)+':'+convert(varchar(5),totalOverTiomeInHoure%3600/60)+':'+convert(varchar(5),(totalOverTiomeInHoure%60)) as overTime
From ( SELECT empId,
Sum(Datediff(s,firstTimeIn,firstTimeOut)) as totalFirstTiomeInHoure,
Sum(Datediff(s,secondTimeIn,secondTimeOut)) as totalSecondTiomeInHoure,
Sum(Datediff(s,overTimeIn,overTimeOut )) as totalOverTiomeInHoure
FROM [dbo].[tbl_EmployeeAttendance]
WHERE attendanceDate BETWEEN '2019-09-01' AND '2019-09-15'
GROUP BY [empId]) as TempData

How to show Datediff hh:ss format?

Running the queries below i get the output '16:6' and '3:40'.
It shows the zero on the second one, but for the first it shows '16:6'
The first one makes it look like '16:60' which by time would be wrong.
How can I make it show '16:06' and not mess up anything else?
SELECT
right('0' + convert(float,datediff (second, '2015-02-09 10:58:42.202','2015-02-09 11:14:48.245')/ 60 ), 2) + ':' +
right('0' + convert(float,datediff (second, '2015-02-09 10:58:42.202','2015-02-09 11:14:48.245')% 60),2) as total_time
SELECT
right('0' + convert(float,datediff (second, '2015-02-09 08:07:35.284','2015-02-09 08:11:15.863')/ 60 ), 2) + ':' +
right('0' + convert(float,datediff (second, '2015-02-09 08:07:35.284','2015-02-09 08:11:15.863')% 60),2) as total_time
Use VARCHAR() instead of FLOAT:
SELECT
right('0' + convert(VARCHAR(4),datediff (second, '2015-02-09 10:58:42.202','2015-02-09 11:14:48.245')/ 60 ), 2) + ':'
+right('0' + convert(VARCHAR(4),datediff (second, '2015-02-09 10:58:42.202','2015-02-09 11:14:48.245')% 60),2) as total_time
The point of the RIGHT('0'+ ... ),2) portion is to add a leading zero to 1-digit values, but it only works on strings.
If you want to show more than 2 digits for the minutes portion you'll have to change how you go about adding leading zeroes.
Assuming this is T-SQL, with one datediff:
SELECT
right(convert(varchar, dateadd(second, datediff(second, '2015-02-09 10:58:42.202','2015-02-09 11:14:48.245'), 0), 108), 5) as total_time

Combining two rows in one select query

Hi I am having a hard time combining two records (from a single table) on a single query. The idea is, DATE_FIELD column is a date type and ColA is an integer data type.
To further illustrate my inquiry, I have attached an image below
1.) Is the raw table.
2.) Is the desired output.
P.S. The filter for DATE_FIELD is not a simple "WHERE DATE_FIELD IN" clause.
For example, I wanted to get the DATE_FIELD=12/30/2013. Then I need to get the Previous Sept DATE_FIELD also, which is 9/30/2013 programatically by using this query that I got from the web:
CASE
WHEN MONTH(DATE_FIELD) < 10
THEN
(cast(CAST((DATE_FIELD) - 1) as char(4)) + RIGHT('00' + LTRIM(09),2) + RIGHT('00' + LTRIM(30),2) AS Date))
ELSE
( cast(CAST((YEAR(DATE_FIELD)) as char(4)) + RIGHT('00' + LTRIM(09),2) + RIGHT('00' + LTRIM(30),2) AS Date))
END
Here is my current sql script (which cannot get the ColA equivalent for Previous Sept filter:
SELECT DATE_FIELD, ColA,
CASE
WHEN MONTH(DATE_FIELD) < 10
THEN
(cast(CAST((YEAR(DATE_FIELD) - 1) as char(4)) + RIGHT('00' + LTRIM(09),2) + RIGHT('00' + LTRIM(30),2) AS Date))
ELSE
( cast(CAST((YEAR(DATE_FIELD)) as char(4)) + RIGHT('00' + LTRIM(09),2) + RIGHT('00' + LTRIM(30),2) AS Date))
END AS PREVIOUS,
(
SELECT ColA
FROM TABLE_A
WHERE DATE_FIELD =
CASE
WHEN MONTH(DATE_FIELD) < 10
THEN
(cast(CAST((YEAR(DATE_FIELD) - 1) as char(4)) + RIGHT('00' + LTRIM(09),2) + RIGHT('00' + LTRIM(30),2) AS Date))
ELSE
( cast(CAST((YEAR(DATE_FIELD)) as char(4)) + RIGHT('00' + LTRIM(09),2) + RIGHT('00' + LTRIM(30),2) AS Date))
END
) AS PYE_colA
FROM TABLE_A
WHERE DATE_FIELD = '12/30/2013'
Thanks!
Do a cross join with the same table and use your CASE structure only in the where clause:
SELECT a.DATE_FIELD AS DATE_FIELD_1,
a.ColA AS ColA_1,
b.DATE_FIELD AS DATE_FIELD_2,
b.ColA AS ColA_2
FROM TABLE_A a
CROSS JOIN TABLE_A b
WHERE DATE_FIELD_1 = 'your date'
AND DATE_FIELD_2 = (
CASE
WHEN MONTH(DATE_FIELD_1) < 10
THEN
(cast(CAST((YEAR(DATE_FIELD_1) - 1) as char(4)) + RIGHT('00' + LTRIM(09),2) + RIGHT('00' + LTRIM(30),2) AS Date))
ELSE
( cast(CAST((YEAR(DATE_FIELD_1)) as char(4)) + RIGHT('00' + LTRIM(09),2) + RIGHT('00' + LTRIM(30),2) AS Date))
END)
;
Another possibility based on Thorsten Kettners remarks:
SELECT a.DATE_FIELD AS DATE_FIELD_1,
a.ColA AS ColA_1,
b.DATE_FIELD AS DATE_FIELD_2,
b.ColA AS ColA_2
FROM TABLE_A a
INNER JOIN TABLE_A b
ON b.DATE_FIELD = (
CASE
WHEN MONTH(a.DATE_FIELD) < 10
THEN
(cast(CAST((YEAR(a.DATE_FIELD) - 1) as char(4)) + RIGHT('00' + LTRIM(09),2) + RIGHT('00' + LTRIM(30),2) AS Date))
ELSE
( cast(CAST((YEAR(a.DATE_FIELD)) as char(4)) + RIGHT('00' + LTRIM(09),2) + RIGHT('00' + LTRIM(30),2) AS Date))
END)
WHERE a.DATE_FIELD = 'your date'
;