I have the following data in a table,
Id
datefrom
dateto
duration
1
2022-05-04 23:59:50.300
2022-05-04 23:59:51.317
1016
2
2022-05-04 23:59:51.317
2022-05-04 23:59:59.410
8094
3
2022-05-04 23:59:59.410
2022-05-05 00:00:00.410
1000
The data is collected for each day and the last record on a day will go over to the next day (unless by pure chance it stops at exactly midnight).
I want to select the data above but re-calculated the last record to "2022-05-04 23:59:59.999" and then get the duration between "2022-05-04 23:59:59.410" and "2022-05-04 23:59:59.999".
So my result would look like,
Id
datefrom
dateto
duration
1
2022-05-04 23:59:50.300
2022-05-04 23:59:51.317
1016
2
2022-05-04 23:59:51.317
2022-05-04 23:59:59.410
8094
3
2022-05-04 23:59:59.410
2022-05-04 23:59:59.999
589
Is this possible in a select?
Thanks,
I can get the last record using,
SELECT MAX(Id) FROM (SELECT * FROM [StatusHistory]) as a
But I'm struggling to get a result of all the data with the last record manipulated.
With some date calculations and a CASE.
However, I disagree with your desired results. The 589 should really be 590 ... or inclusive of the last millisecond up until midnight
Example
Declare #YourTable Table ([Id] int,[datefrom] datetime,[dateto] datetime,[duration] int)
Insert Into #YourTable Values
(1,'2022-05-04 23:59:50.300','2022-05-04 23:59:51.317',1016)
,(2,'2022-05-04 23:59:51.317','2022-05-04 23:59:59.410',8094)
,(3,'2022-05-04 23:59:59.410','2022-05-05 00:00:00.410',1000)
Select *
,NewVal = datediff(MILLISECOND,datefrom,case when convert(date,dateto)=convert(date,datefrom) then dateto else convert(date,datefrom+1) end)
from #YourTable
Results
I have two temp tables
#shovel
Equipment Code Start_Time
EX7016 1000 0
EX7016 4030 1200
EX7016 1000 1400
#truck
Equipment Shovel Code Start_Time
DT5188 EX7016 1002 0
DT5188 EX7016 1003 1000
DT5188 EX7016 1004 1500
DT5188 EX7016 1005 2000
The logic I need is if the #shovel table has code > 2000, and the time starts when the truck is in a 1003 code, then insert that time into the #truck table as a 1002 code. And once the Shovel goes back into a 1000 code, insert that time as a 1003 code, so it looks like:
Equipment Shovel Code Start_Time
DT5188 Ex7016 1002 0
DT5188 Ex7016 1003 1000
DT5188 Ex7016 1002 1200
DT5188 Ex7016 1003 1400
DT5188 Ex7016 1004 1500
DT5188 Ex7016 1005 2000
I had a quick try at this, and here's a solution that works in multiple steps. It's probably not fit for purpose, but at least it's a start.
IF OBJECT_ID('tempdb..#shovel') IS NOT NULL
DROP TABLE #shovel;
IF OBJECT_ID('tempdb..#truck') IS NOT NULL
DROP TABLE #truck;
IF OBJECT_ID('tempdb..#matches1') IS NOT NULL
DROP TABLE #matches1;
IF OBJECT_ID('tempdb..#matches2') IS NOT NULL
DROP TABLE #matches2;
SELECT 'EX7016' AS Equipment, '1000' AS Code, '0' AS Start_Time
INTO #shovel
UNION ALL
SELECT 'EX7016' AS Equipment, '4030' AS Code, '1200' AS Start_Time
UNION ALL
SELECT 'EX7016' AS Equipment, '1000' AS Code, '1400' AS Start_Time
SELECT 'DT5188' AS Equipment, 'EX7016' AS Shovel, '1002' AS Code, '0' AS Start_Time
INTO #truck
UNION ALL
SELECT 'DT5188' AS Equipment, 'EX7016' AS Shovel, '1003' AS Code, '1000' AS Start_Time
UNION ALL
SELECT 'DT5188' AS Equipment, 'EX7016' AS Shovel, '1004' AS Code, '1500' AS Start_Time
UNION ALL
SELECT 'DT5188' AS Equipment, 'EX7016' AS Shovel, '1005' AS Code, '2000' AS Start_Time;
--Make a list of cases where the #shovel table has code > 2000, and the time starts when the truck is in a 1003 code
SELECT
s.Equipment,
s.Start_Time,
t.Shovel
INTO
#matches1
FROM
#shovel s
INNER JOIN #truck t ON t.Shovel = s.Equipment
WHERE
s.Code > '2000'
AND t.Code = '1003';
--Find cases where the shovel goes back to a 1000 code
SELECT
m.Equipment,
s.Start_Time,
m.Shovel
INTO
#matches2
FROM
#matches1 m
INNER JOIN #shovel s ON s.Equipment = m.Equipment AND s.Start_Time > m.Start_Time AND s.Code = '1000';
--Finally, insert matching rows back into the #truck table (do we only do this if there is a match in both tables?)
INSERT INTO #truck SELECT Equipment, Shovel, '1002' AS Code, Start_Time FROM #matches1;
INSERT INTO #truck SELECT Equipment, Shovel, '1003' AS Code, Start_Time FROM #matches2;
SELECT * FROM #truck ORDER BY Start_Time;
Apologies me for the title as it might different than the actual issue
We are working for Contact Centers and our SQL Server tables will be capturing detailed information of Agent's going for Breaks, Login and Logout with Time, Duration and Reason.
When an agent going for Lunch #2PM and changing his state to Break #2:10Pm, then DB will update with Lunch Duration 600 Seconds. ie. After changing the state in Agent Screen, DB will insert the End Time and the duration occurred for that particular break reason.
If an event(Break) is continuing beyond 30 minutes, this table will put an entry for every 30 minutes until the agent changing his current state example below,
Table raw data:
Agent Name SkilltargetID Event Date Time ReasonText Duration
Sathiya 5000 3 20-08-2018 10:00 BioBreak 180 Seconds
Sathiya 5000 3 20-08-2018 10:30 BioBreak 1800 Seconds
Sathiya 5000 3 20-08-2018 11:00 BioBreak 1800 Seconds
Sathiya 5000 3 20-08-2018 11:30 BioBreak 1800 Seconds
Sathiya 5000 3 20-08-2018 11:42 BioBreak 720 Seconds
Sathiya 5000 3 20-08-2018 12:01 Lunch 1140 Seconds
Sathiya 5000 3 20-08-2018 12:30 Lunch 1740 Seconds
Sathiya 5000 3 20-08-2018 12:32 Lunch 120 Seconds
Sathiya 5000 3 20-08-2018 01:00 Bio Break 1680 Seconds
Sathiya 5000 3 20-08-2018 01:29 Bio Break 1740 Seconds
We have a report that will show Date, Agent Name, Start Time, End Time, ReasonText(Break Reason) and Duration.
Expected Output:
Date Agent Name SkillTargetID Event Start Time End Time Reason Duration
20-08-2018 Sathiya 5000 3 9:57 AM 11:42 AM Bio Break 6300
20-08-2018 Sathiya 5000 3 12:01 AM 12:32 AM Lunch 3000
20-08-2018 Sathiya 5000 3 12:32 AM 1:29 PM Bio Break 3420
Actual Output:
Date Agent Name SkillTargetID Event Start Time End Time Reason Duration
20-08-2018 Sathiya 5000 3 9:57 AM 10:00 AM Bio Break 180
20-08-2018 Sathiya 5000 3 10:00 AM 11:30 AM Bio Break 5400
20-08-2018 Sathiya 5000 3 11:30 AM 11:42 AM Bio Break 720
20-08-2018 Sathiya 5000 3 11:42 AM 12:01 AM Lunch 1140
20-08-2018 Sathiya 5000 3 12:01 AM 12:30 AM Lunch 1740
20-08-2018 Sathiya 5000 3 12:30 AM 12:32 AM Lunch 120
20-08-2018 Sathiya 5000 3 12:32 AM 1:00 AM Bio Break 1680
20-08-2018 Sathiya 5000 3 1:00 AM 1:29 AM Bio Break 1740
We are trying to achieve using below query,
;WITH RCode ( ReasonCodeID, ReasonCode,ReasonText, Description )
AS (
Select ReasonCodeID, ReasonCode,ReasonText, Description From Reason_Code
Union All
Select 9999,0,'Not Ready-Default', 'Not Ready-System Predefined'
Union All
Select 9999,-1,'Agent reinitialized (used if peripheral restarts)', 'Not Ready-System Predefined'
Union All
Select 9999,-2,'PG reset the agent, normally due to a PG failure', 'Not Ready-System Predefined'
Union All
Select 9999,-3,'An administrator modified the agent''s extension while the agent was logged in', 'Not Ready-System Predefined'
Union All
Select 9999,50002,'A CTI OS component failed, causing the agent to be logged out', 'Not Ready-System Predefined'
Union All
Select 9999,50003,'Agent was logged out because the Unified CM reported the device out of service', 'Not Ready-System Predefined'
Union All
Select 9999,50004,'Agent was logged out due to agent inactivity as configured in agent desk settings', 'Not Ready-System Predefined'
Union All
Select 9999,50005,'The Agent will be set to not ready with this code while talking on a call on the Non ACD line', 'Not Ready-System Predefined'
Union All
Select 9999,50020,'Agent was logged out when the agent''s skill group dynamically changed on the Administration & Data Server', 'Not Ready-System Predefined'
Union All
Select 9999,50040,'Mobile agent was logged out because the call failed', 'Not Ready-System Predefined'
Union All
Select 9999,50041,'Mobile agent state changed to Not Ready because the call fails when the mobile agent''s phone line rings busy.', 'Not Ready-System Predefined'
Union All
Select 9999,50042,'Mobile agent was logged out because the phone line disconnected while using nailed connection mode', 'Not Ready-System Predefined'
Union All
Select 9999,32767,'The agent''s state was changed to Not Ready because the agent did not answer a call and the call was redirected to a different agent or skill group', 'Not Ready-System Predefined'
),
CTE ( RowNum, SerialNum, DateTime, SkillTargetID, Event, Duration, ReasonCode)
AS (
SELECT
RowNum = ROW_NUMBER() OVER (PARTITIOn BY SkillTargetID ORDER BY DateTime, SkillTargetID),
SerialNum = ROW_NUMBER() OVER (PARTITION BY SkillTargetID, Event,Duration ORDER BY DateTime),
DateTime, SkillTargetID, Event, Duration, ReasonCode
FROM
(Select DateTime,SkillTargetID, Event,
CASE WHEN (Duration=899 OR Duration=898 OR Duration=901 OR Duration=900) THEN 900
WHEN (Duration=1799 OR Duration=1798 OR Duration=1801 OR Duration=1800) THEN 1800
ELSE Duration end as 'Duration',
ReasonCode,RecoveryKey From TABLEA Where
SkillTargetID IN (5259)
And (Convert(varchar(10),DateTime,110)>= '07-10-2018' and convert(varchar(10),DateTime,110) <= '07-10-2018') ) A
)
--select * from CTE
,
CTE2 AS (
Select [Activity], Convert(varchar(10), [Activity], 101) AS [Date],
Stuff(right(convert(varchar(30), [Activity], 109), 14), 9, 4, ' ') AS [End Time],
SkillTargetID, [Agent Name], Event, [Duration], Z.ReasonCode [Reason Code], R.ReasonText [Reason], PrevDateTime,CTEDateTime, RowNum,SerialNum,PrevRow,CTENewRow From
(Select CTE.RowNum RowNum, CTE.SerialNum SerialNum, CTE.DateTime CTEDateTime, CTE.SkillTargetID,
(Select B.LastName +', '+B.FirstName From Agent (nolock) Join Person B On Agent.PersonID = B.PersonID Where SkillTargetID=CTE.SkillTargetID) [Agent Name], prev.DateTime PrevDateTime, prev.RowNum PrevRow,((CTE.RowNum-CTE.SerialNum)+1) CTENewRow,
Event = CASE WHEN CTE.Event = 1 THEN 'Sign-on' WHEN CTE.Event=2 THEN 'Sign-off' WHEN CTE.Event=3 THEN 'Not-Ready' Else 'Unknown' END,
CTE.Duration, CTE.ReasonCode,
[Activity] = CASE WHEN (CTE.Event = 3 AND CTE.Duration=1800 and CTE.SerialNum=1) THEN CTE.DateTime
WHEN (CTE.Event = 3 AND CTE.Duration=900 and CTE.SerialNum=1) THEN CTE.DateTime
WHEN (CTE.Event = 3 AND CTE.Duration=1800 and CTE.SerialNum<>1) THEN prev.DateTime
WHEN (CTE.Event = 3 AND CTE.Duration=900 and CTE.SerialNum<>1) THEN prev.DateTime
ELSE CTE.DateTime
END
FROM CTE
LEFT JOIN CTE prev ON prev.RowNum = (CTE.RowNum-CTE.SerialNum)+1 AND prev.SkillTargetID=CTE.SkillTargetID
)
Z LEFT JOIN RCode R ON R.ReasonCode = Z.ReasonCode
)
--Select * From CTE2 where [Reason Code]=107 ORDER BY Activity, [Agent Name]
Select Activity, Date, Stuff(right(convert(varchar(30), DATEADD(second, -(Sum(Duration)),[Activity]), 109), 14), 9, 4, ' ') AS [Start Time],
[End Time], SkillTargetID, [Agent Name], Event, SUM(Duration) AS [Duration], [Reason Code], Reason From CTE2
Where [Reason Code]=107
GROUP BY [Activity], Date, [End Time], SkillTargetID, [Agent Name], Event, [Reason Code], Reason
Order By [Agent Name], Activity
Query Logic:
We are showing Event StartTime and EndTime from TABLEA table by considering Row Number and Serial Number,
RowNum = ROW_NUMBER() OVER (PARTITION BY SkillTargetID ORDER BY DateTime, SkillTargetID),
SerialNum = ROW_NUMBER() OVER (PARTITION BY SkillTargetID, Event,Duration ORDER BY DateTime),
From TABLEA.
After fetching the RowNum and SerialNum, we are selecting a field called Activity based on those RowNum and SerialNum values,
[Activity] = CASE WHEN (CTE.Event = 3 AND CTE.Duration=1800 and CTE.SerialNum=1) THEN CTE.DateTime
WHEN (CTE.Event = 3 AND CTE.Duration=900 and CTE.SerialNum=1) THEN CTE.DateTime
WHEN (CTE.Event = 3 AND CTE.Duration=1800 and CTE.SerialNum<>1) THEN prev.DateTime
WHEN (CTE.Event = 3 AND CTE.Duration=900 and CTE.SerialNum<>1) THEN prev.DateTime
ELSE CTE.DateTime
END
FROM CTE
LEFT JOIN CTE prev ON prev.RowNum = (CTE.RowNum-CTE.SerialNum)+1 AND prev.SkillTargetID=CTE.SkillTargetID
Start Time and End Time values are based on the above [Activity]. But it is showing incorrect data.
Reason for this issue:
If SerialNum is based on SkillTargetID, Event, Duration it is showing different values for same entry and showing 1 for different entries as expected and due to that if we have below scenario we are getting incorrect Start Time and End Time and in the report.
Agent Name SkillTargetID Event Date Time ReasonText Duration
Sathiya 5000 3 20-08-2018 10:00 BioBreak 150 Seconds
Sathiya 5000 3 20-08-2018 10:30 BioBreak 1800 Seconds
Sathiya 5000 3 20-08-2018 11:00 BioBreak 1800 Seconds
Sathiya 5000 3 20-08-2018 11:30 BioBreak 1800 Seconds
Sathiya 5000 3 20-08-2018 11:42 BioBreak 720 Seconds
SerialNum value will show 1 for First Record as well as last record due to this query is thinking they are different events and not the same but actually all are same continues event that should show as in single row in the report.
As per what I have understood,if output is not ok then care to reexplain the requirement.
Sample data,
create table #temp (AgentName varchar(50), SkilltargetID int, Events int, EventTimes datetime, ReasonText varchar(50), Duration int)
insert into #temp values
('Sathiya', 5000, 3, '2018-08-20 10:00', 'BioBreak', 180 )
,('Sathiya', 5000, 3, '2018-08-20 10:30', 'BioBreak', 1800 )
,('Sathiya', 5000, 3, '2018-08-20 11:00', 'BioBreak', 1800 )
,('Sathiya', 5000, 3, '2018-08-20 11:30', 'BioBreak', 1800 )
,('Sathiya', 5000, 3, '2018-08-20 11:42', 'BioBreak', 720 )
,('Sathiya', 5000, 3, '2018-08-20 12:01', 'Lunch', 1140 )
,('Sathiya', 5000, 3, '2018-08-20 12:30', 'Lunch', 1740 )
,('Sathiya', 5000, 3, '2018-08-20 12:32', 'Lunch', 120 )
,('Sathiya', 5000, 3, '2018-08-20 01:00', 'BioBreak', 1680 )
,('Sathiya', 5000, 3, '2018-08-20 01:29', 'BioBreak', 1740 )
Script,
;With CTE as
(
select AgentName,SkilltargetID,Events
,ReasonText ,Duration,EventTimes
,ROW_NUMBER()over( order by(select null))rn
from #temp
)
,CTE1 as
(
select AgentName,SkilltargetID,Events
,ReasonText ,Duration,EventTimes
,rn
,1 groupid
from cte
where rn=1
union all
select c.AgentName,c.SkilltargetID,c.Events
,c.ReasonText ,c.Duration,c.EventTimes
,c.rn
,case when c.ReasonText=c1.ReasonText then groupid else groupid+1 end
from cte c
inner join cte1 c1 on c.rn=c1.rn+1
)
,cte3 as
(
select AgentName,SkilltargetID,Events,ReasonText,groupid
,ROW_NUMBER()over(partition by groupid order by EventTimes desc)rownum
,EventTimes
from CTE1
)
,cte2 as
(
select groupid,sum(duration) Duration from CTE1
group by groupid
)
select AgentName,SkilltargetID,Events,ReasonText
,convert(varchar,cast( dateadd(second,-c2.Duration, c3.EventTimes) as time),100)StartTime
,convert(varchar,cast(c3.EventTimes as time),100) EndTime
,Duration
from cte3 c3
inner join cte2 c2
on c3.groupid=c2.groupid
where c3.rownum=1
drop table #temp
I am on SQL Server 2008 and I have a table containing WA metrics of the following form :
CREATE TABLE #VistitorStat
(
datelow datetime,
datehigh datetime,
name varchar(255),
cnt int
)
Two days worth of data in the table looks like so:
2009-07-25 00:00:00.000 2009-07-26 00:00:00.000 New Visitor 221
2009-07-25 00:00:00.000 2009-07-26 00:00:00.000 Unique Visitors 225
2009-07-25 00:00:00.000 2009-07-26 00:00:00.000 Return Visitors 0
2009-07-25 00:00:00.000 2009-07-26 00:00:00.000 Repeat Visitors 22
2009-07-26 00:00:00.000 2009-07-27 00:00:00.000 New Visitor 263
2009-07-26 00:00:00.000 2009-07-27 00:00:00.000 Unique Visitors 269
2009-07-26 00:00:00.000 2009-07-27 00:00:00.000 Return Visitors 4
2009-07-26 00:00:00.000 2009-07-27 00:00:00.000 Repeat Visitors 38
I want to group by the days and pivot the metrics into row form. The examples for using the PIVOT operator that I can find only show aggregation based on the SUM and MAX aggregate function. Presumably I need to convey GROUP BY semantics to the PIVOT operator -- note: I can't find any clear examples/ documentation on how to achieve this. Could someone please post the correct syntax of this -- with the use of the PIVOT operator -- of this query.
If this is not possible with pivot -- can you come up with an elegant way of writing the query ? If not I'll just have to generate the data in transposed form.
Post answer edit:
I have come to the conclusion that the pivot operator is unelegant (so far so that I consider it a syntax hack) -- I have solved the problem by generating the data in a transposed fashion. I welcome comments.
I m not sure of the result you want but this gives a line per day:
CREATE TABLE #VistitorStat
(
datelow datetime,
datehigh datetime,
name varchar(255),
cnt int
)
insert into #VistitorStat
select '2009-07-25 00:00:00.000','2009-07-26 00:00:00.000', 'New Visitor', 221
union select '2009-07-25 00:00:00.000',' 2009-07-26 00:00:00.000', 'Unique Visitors', 225
union select '2009-07-25 00:00:00.000',' 2009-07-26 00:00:00.000', 'Return Visitors', 0
union select '2009-07-25 00:00:00.000',' 2009-07-26 00:00:00.000', 'Repeat Visitors', 22
union select '2009-07-26 00:00:00.000',' 2009-07-27 00:00:00.000', 'New Visitor' , 263
union select '2009-07-26 00:00:00.000',' 2009-07-27 00:00:00.000', 'Unique Visitors', 269
union select '2009-07-26 00:00:00.000',' 2009-07-27 00:00:00.000', 'Return Visitors', 4
union select '2009-07-26 00:00:00.000',' 2009-07-27 00:00:00.000', 'Repeat Visitors', 38
select * from #VistitorStat
pivot (
sum(cnt)
for name in ([New Visitor],[Unique Visitors],[Return Visitors], [Repeat Visitors])
) p