Input the output of one query into second query - sql

I have two sets of queries. First, I calculate the median in seconds to complete transactions for a given period of time. The second query converts the median time retrieved in the first query to date format (DD:HH:MI:SS).
I manually input the output result (calculated median) of the first query into the second query to get my desired result (days hours minutes seconds), this works well. But I wanted a situation where I could combine these two queries into one without manually inputting the time in the second query. See the queries below:
SELECT TxnStartDT, TxnCompleteDT, TxnDuration,
PERCENTILE_CONT(.5) WITHIN GROUP (ORDER BY TxnDuration) OVER() AS MEDIAN
FROM(
SELECT DISTINCT TxnStartDT, TxnCompleteDT,
DATEDIFF(SECOND, TxnStartDT, TxnCompleteDT) AS TxnDuration
FROM MyTable
WHERE (TxnStartDT >='2023-01-02 00:00' and TxnStartDT <= '2023-01-08 23:59') and TxnCompleteDT is not null) AS D
Output
MEDIAN
7333
DECLARE #MD DATETIME = DATEADD(SECOND, 7333, 0)
SELECT --CAST(DATEPART(MONTH, #VARDT) - 1 AS VARCHAR(2)) + ' month(s) '
+ CAST(DATEPART(DAY, #MD) - 1 AS VARCHAR(2)) + ' day(s) '
+ CAST(DATEPART(HOUR, #MD) AS VARCHAR(2)) + ' hour(s) '
+ CAST(DATEPART(MINUTE, #MD) AS VARCHAR(2)) + ' minute(s) '
+ CAST(DATEPART(SECOND, #MD) AS VARCHAR(2)) + ' second(s)' as 'Median Time'
Output
0 day(s) 2 hour(s) 2 minute(s) 13 second(s)
I tried to use the CAST function so that I could run the queries once without running the two queries separately. I got errors.
SELECT TxnStartDT, TxnCompleteDT, TxnDuration,
PERCENTILE_CONT(.5) WITHIN GROUP (ORDER BY TxnDuration) OVER() AS MEDIAN
FROM(
SELECT DISTINCT TxnStartDT, TxnCompleteDT,
DATEDIFF(SECOND, TxnStartDT, TxnCompleteDT) AS TxnDuration
FROM MyTable
WHERE (TxnStartDT >='2023-01-02 00:00' and TxnStartDT <= '2023-01-08 23:59') and TxnCompleteDT is not null) AS D
DECLARE #MD DATETIME = CAST(DATEADD(SECOND, MEDIAN, 0))
SELECT --CAST(DATEPART(MONTH, #VARDT) - 1 AS VARCHAR(2)) + ' month(s) '
+ CAST(DATEPART(DAY, #MD) - 1 AS VARCHAR(2)) + ' day(s) '
+ CAST(DATEPART(HOUR, #MD) AS VARCHAR(2)) + ' hour(s) '
+ CAST(DATEPART(MINUTE, #MD) AS VARCHAR(2)) + ' minute(s) '
+ CAST(DATEPART(SECOND, #MD) AS VARCHAR(2)) + ' second(s)' as 'Median Time'
Errors
Msg 1035, Level 15, State 10, Line 32 Incorrect syntax near
'CAST', expected 'AS'. Msg 137, Level 15, State 2, Line 34
Must declare the scalar variable "#MD".

try this
;with cte as(SELECT TxnStartDT, TxnCompleteDT, TxnDuration,
cast (DATEADD(SECOND,PERCENTILE_CONT(.5) WITHIN GROUP (ORDER BY TxnDuration) OVER() ,0)as datetime) AS MEDIAN
FROM(
SELECT DISTINCT TxnStartDT, TxnCompleteDT,
DATEDIFF(SECOND, TxnStartDT, TxnCompleteDT) AS TxnDuration
FROM MyTable
WHERE (TxnStartDT >='2023-01-02 00:00' and TxnStartDT <= '2023-01-08 23:59') and TxnCompleteDT is not null) AS D)
SELECT
CAST(DATEPART(DAY, MEDIAN) - 1 AS VARCHAR(2)) + ' day(s) '
+ CAST(DATEPART(HOUR, MEDIAN) AS VARCHAR(2)) + ' hour(s) '
+ CAST(DATEPART(MINUTE, MEDIAN) AS VARCHAR(2)) + ' minute(s) '
+ CAST(DATEPART(SECOND, MEDIAN) AS VARCHAR(2)) + ' second(s)' as 'Median Time'
from cte

Related

How to find an average time to complete a task for a given period [duplicate]

This question already has answers here:
How to reuse calculated columns avoiding duplicating the sql statement
(6 answers)
Possible to store value of one select column and use it for the next one?
(4 answers)
Closed 6 months ago.
I am trying to find an average time to complete a task for a given period, for example, between 2022-07-01 and 2022-07-23. My table has received and completed date timestamps columns as shown below. My queries work, but I want to combine my two separate queries into one. It would also be helpful if someone could help me with a simpler method to get my desired result.
Received_date
Completed_date
2022-07-01 14:06:16.000
2022-07-01 14:06:00.000
2022-07-01 14:03:48.000
2022-07-01 14:04:00.000
.
.
.
.
2022-07-23 09:05:25.000
2022-07-23 10:53:00.000
Code 1 -Average time in seconds to complete request
SELECT AVG(ABS(DATEDIFF(SECOND, Completed_date, Received_date )) ) as 'Average time in seconds to complete request'
FROM Mytable
WHERE Completed_date >='2022-07-01 00:00' and Completed_date <= '2022-07-23 23:59'
Output
Average time in seconds to complete request
149408
Code 2 -Average time to complete a task for a given period
DECLARE #AVG_TIME DATETIME = DATEADD(SECOND, 149408, 0)
SELECT ( CAST(DATEPART(MONTH, #AVG_TIME) - 1 AS VARCHAR(2)) + ' month(s) ' + CAST(DATEPART(DAY, #AVG_TIME) - 1 AS VARCHAR(2)) + ' day(s) ' + CAST(DATEPART(HOUR, #AVG_TIME) AS VARCHAR(2)) + ' hour(s) '+ CAST(DATEPART(MINUTE, #AVG_TIME) AS VARCHAR(2)) + ' minute(s) ' + CAST(DATEPART(SECOND, #AVG_TIME) AS VARCHAR(2)) + ' second(s)' ) as 'Average time to complete a task for a given period'
Output
Average time to complete a task for a given period
0 month(s) 1 day(s) 17 hour(s) 30 minute(s) 8 second(s)
This is what I mean. It combines both your queries, regardless of the source table.
DECLARE #AVG_TIME DATETIME = DATEADD(SECOND, 149408, 0)
;With CTE1 as (
SELECT ID, AVG(ABS(DATEDIFF(SECOND, Completed_date, Received_date )) ) as 'Average time in seconds to complete request'
FROM Mytable
WHERE Completed_date >='2022-07-01 00:00' and Completed_date <= '2022-07-23 23:59')
,CTE2 as (
SELECT ID, ( CAST(DATEPART(MONTH, #AVG_TIME) - 1 AS VARCHAR(2)) + ' month(s) ' + CAST(DATEPART(DAY, #AVG_TIME) - 1 AS VARCHAR(2)) + ' day(s) ' + CAST(DATEPART(HOUR, #AVG_TIME) AS VARCHAR(2)) + ' hour(s) '+ CAST(DATEPART(MINUTE, #AVG_TIME) AS VARCHAR(2)) + ' minute(s) ' + CAST(DATEPART(SECOND, #AVG_TIME) AS VARCHAR(2)) + ' second(s)' ) as 'Average time to complete a task for a given period'
)
select *
from CTE1
join CTE2 on cte1.ID = CTE2.ID

Employee Total Experience SQL query

I have table with employees work experience. I want to get summary experience in format like yy mm dd.
e_id work_from work_to
2 2003-10-13 2004-02-12
2 2004-02-16 2004-06-30
2 2004-07-01 2006-01-31
2 2006-02-01 2017-07-12
Result should be: 13Y 8M 27D
Query like:
sum(datediff(month,work_from,work_to))/12,
sum(datediff(month,work_from,work_to)%12
works fine, but what about days?
Please note, the following query is a general summation which does not include leap years and the months are averaged between 365/12 in days since the amount of days in each month vary. If you want an exact figure that includes the exact amount of days, the algorithm will be more involved, but hopefully this gets you in a reasonably close ballpark figure.
SELECT CONVERT(VARCHAR(10), sum(datediff(year,work_from,work_to))-1) + 'Y' AS Years,
CONVERT(VARCHAR(10), FLOOR((sum(datediff(day, work_from,work_to)) - ((sum(datediff(year,work_from,work_to)) - 1) * 365)) / 30.4166)) + 'M' AS Months,
CONVERT(VARCHAR(10), CEILING(sum(datediff(day, work_from,work_to)) - ((sum(datediff(year,work_from,work_to)) - 1) * 365) - (FLOOR((sum(datediff(day, work_from,work_to)) - ((sum(datediff(year,work_from,work_to)) - 1) * 365)) / 30.4166) * 30.4166))) + 'D' AS Days,
CONVERT(VARCHAR(10), sum(datediff(day,work_from,work_to))) AS Total_Days
Here is my solution. This is the closest I can get. The problem that I had is that I cant escape the M after month.
DECLARE #SumExp Datetime = (SELECT CONCAT(
DATENAME(day, (SELECT SUM(DATEDIFF(day, WorkFrom, WorkTo))
FROM EmployeeWorkExperience)),
DATENAME(month, (SELECT SUM(DATEDIFF(day, WorkFrom, WorkTo))
FROM EmployeeWorkExperience)),
DATENAME(year, (SELECT SUM(DATEDIFF(day, WorkFrom, WorkTo))
FROM EmployeeWorkExperience))))
SELECT REPLACE(FORMAT(#SumExp, 'yyY MM# ddD'), '#', 'M')
DECLARE #work TABLE(
WorkId INT IDENTITY(1,1) PRIMARY KEY ,
work_from DATETIME NOT NULL,
work_to DATETIME NOT NULL )
INSERT INTO #work
( work_from, work_to )
VALUES ( '10/13/2003',
'2/12/2004'
),
(
'2/16/2004',
'6/30/2004'
),
('7/1/2004',
'1/31/2006'
),
('2/1/2006',
'7/12/2017'
)
DECLARE #seconds int
SELECT #seconds = SUM(DATEDIFF(SECOND, work_from, work_to))
FROM #work
DECLARE #VARDT DATETIME = DATEADD(SECOND, #seconds, 0)
SELECT CAST(DATEPART(YEAR, #VARDT) - 1900 AS VARCHAR(10)) + ' year(s) ' + CAST(DATEPART(MONTH, #VARDT) - 1 AS VARCHAR(2)) + ' month(s) '
+ CAST(DATEPART(DD, #VARDT) - 1 AS VARCHAR(2)) + ' day(s) ' + CAST(DATEPART(HOUR, #VARDT) AS VARCHAR(2)) + ' hour(s) '
+ CAST(DATEPART(MINUTE, #VARDT) AS VARCHAR(2)) + ' minute(s) ' + CAST(DATEPART(SECOND, #VARDT) AS VARCHAR(2)) + ' second(s)'

Concatenating two TIME columns in SQL Server 2012

I want to concatenate two TIME columns and show as one column.
Example:
FromTime: 9:00
ToTime: 12:00
Result should be:
9:00-12:00
Generic SQL:
-- hh:mm:ss
SELECT 'result:' + CONVERT(CHAR(6), FromTime, 8) + '-' + CONVERT(CHAR(6), ToTime)
FROM yourTable
MySQL:
-- hh:mm
SELECT 'result:' + DATE_FORMAT(FromTime, '%H:%i') + '-' + DATE_FORMAT(ToTime, '%H:%i')
FROM yourTable
SQL Server:
-- hh:mm
SELECT 'result:' + convert(char(2), DATEPART(hh, FromTime)) + ':' +
CONVERT(CHAR(2), DATEPART(mm, FromTime)) + '-' +
CONVERT(CHAR(2), DATEPART(hh, ToTime)) + ':' +
CONVERT(CHAR(2), DATEPART(mm, ToTime))
FROM yourTable
declare #FromTime time
declare #ToTime time
set #FromTime='9:00'
set #ToTime='12:00'
select cast(#FromTime as varchar(10))+ '-' + cast(#ToTime as varchar(10)) as result
sql demo
You can use convert
select convert(VARCHAR(5),getdate(),108) + ' - ' + convert(VARCHAR(5),getdate()-1,108)

Using DatePart in line of a larger sql clause

This statement will correctly merge 2 columns ('DATE' and 'TIME'):
update AllBW1 set sUserTime =
CAST(
(
STR( YEAR( [DATE] ) ) + '/' +
STR( MONTH( [DATE] ) ) + '/' +
STR( DAY( [DATE] ) ) + ' ' +
(select DATENAME(hour, [TIME]))+ ':' +
(select DATENAME(minute, [TIME])) + ':' +
(select DATENAME(SECOND, [TIME]))
) as DATETIME)
where sUserTime is null
I'd like to refine the above so as to replace the default timezone with my own (GMT-6).
I've tried a few variations:
CAST((select DATEADD(hour, -6, DATENAME(hour, [TIME]))) as smalldatetime) + ':' +
and
(select CAST(DATEADD(hour, -6, DATENAME(hour, [TIME]))) as datetime) + ':' +
and have achieved no joy.
thx
The logfile as parsed into the SQL table by LogParser 2.2 has separate fields for Date and Time but, since both are formatted as datatime fields they end up looking like:
2012-01-04 00:00:00.000 for date (all time fields are zeroed)
2012-01-01 06:04:41.000 for time (all date field = first day of current year)
That's the reason the query is parsing each element the way it is. Thanks to Dems comment I simplified everything down. I've no doubt this can be optimized by for the volumes I'm dealing with this is adaquate:
update myTable set sUserTime =
(
DATENAME(YEAR, [DATE] ) + '/' +
DATENAME(MONTH, [DATE] ) + '/' +
DATENAME(DAY, [DATE] ) + ' ' +
DATENAME(hour, (dateadd(hh, -6, [time])))+ ':' +
DATENAME(minute, [TIME]) + ':' +
DATENAME(SECOND, [TIME])
)
where sUserTime is null

How to convert date into DD-MON-YYYY HH24:MI:SS format?

Can someone help me with SQL Date format?
The following statement
SELECT convert(VARCHAR(20),GETDATE(),113)
returns
04 Aug 2011 08:08:08.
I want the results like
Aug-04-2011 08:08:08
Thank you!
SELECT
LEFT(DATENAME(MONTH, Date), 3) + '-' +
RIGHT(100 + DAY(Date), 2) + '-' +
DATENAME(YEAR, Date) + ' ' +
CONVERT(varchar, Date, 108)
FROM (SELECT Date = GETDATE()) s
Off the top of my head, I think its:
SELECT convert(VARCHAR(20),GETDATE(),120)
EDIT:
This will work:
SELECT datename(day, GETDATE()) + '-'
+ substring(datename(month, GETDATE()),0,4) + '-'
+ datename(year, GETDATE()) + ' '
+ datename(hh, GETDATE()) + ':'
+ datename(mi, GETDATE()) + ':'
+ datename(ss, GETDATE())
SECOND EDIT:
SELECT substring(datename(month, GETDATE()),0,4) + '-'
+ datename(day, GETDATE()) + '-'
+ datename(year, GETDATE()) + ' '
+ datename(hh, GETDATE()) + ':'
+ datename(mi, GETDATE()) + ':'
+ datename(ss, GETDATE())
THIRD EDIT:
select substring(datename(month, GETDATE()),0,4) + '-'
+ right(datename(day, GETDATE())+100,2) + '-'
+ datename(year, GETDATE()) + ' '
+ right(datename(hh, GETDATE())+100,2) + ':'
+ right(datename(mi, GETDATE())+100,2) + ':'
+ right(datename(ss, GETDATE())+100,2)
The built-in convert won't allow you to format your date exactly as you desire, unfortunately.
With a little manipulation, you can get there though:
SELECT stuff(stuff(convert(VARCHAR(20),GETDATE(),113), 3, 1, '-'), 7, 1, '-')
You could put this in a UDF and call that whenever you want your date formatted in this manner.