-
Viorel 88,571 Reputation points
2021-11-08T16:47:48.337+00:00 To include the additional ActionEndDate:
select i.USERID, i.CUSTOMERID, s.ACTION_DATE, e.ACTION_DATE as ActionEndDate, i.ACTION from @INPUT i cross apply ( select top(1) * from @INPUT where USERID = i.USERID and CUSTOMERID=i.CUSTOMERID and cast(ACTION_DATE as date) = cast(i.ACTION_DATE as date) and ACTION_DATE <= i.ACTION_DATE and ACTION in ( 'ACSCEVNT', 'NEXTCNSM' ) order by ACTION_DATE, ID desc ) s cross apply ( select top(1) * from @INPUT where USERID = i.USERID and CUSTOMERID=i.CUSTOMERID and cast(ACTION_DATE as date) = cast(i.ACTION_DATE as date) and ACTION_DATE >= i.ACTION_DATE and ACTION not in ( 'ACSCEVNT', 'NEXTCNSM' ) order by ACTION_DATE desc, ID desc ) e where i.ACTION not in ( 'ACSCEVNT', 'NEXTCNSM' ) order by USERID, ACTION_DATE
-
Eshwar 176 Reputation points
2021-11-09T04:57:25.253+00:00 @Viorel
One last scenario.. looking on converting datetime to date will not work as there will scenario when user1 worked on a customer then he went to a new customer and came back to old customer then those should be considered as separate records for that customerInput:
Expected Output:
Query:
147622-queries.txtPlease help!
Thanks,
EshwarViorel 88,571 Reputation points2021-11-09T10:47:38.427+00:00 It seems that the sample script (147622-queries.txt) cannot be opened.
Eshwar 176 Reputation points2021-11-09T12:21:17.477+00:00 @Viorel
Attaching
147719-queries.txtViorel 88,571 Reputation points2021-11-09T13:13:47.53+00:00 Try the adjusted query:
; with Q as ( select *, g = dense_rank() over (partition by USERID, CUSTOMERID order by ID) - dense_rank() over (partition by USERID order by ID) from @INPUT ) select i.USERID, i.CUSTOMERID, ActionDate = s.ACTION_DATE, ActionEndDate = e.ACTION_DATE, i.ACTION from Q i cross apply ( select top(1) * from Q where USERID = i.USERID and CUSTOMERID=i.CUSTOMERID and g=i.g and ID < i.ID and ACTION in ( 'ACSCEVNT', 'NEXTCNSM' ) order by ID ) s cross apply ( select top(1) * from Q where USERID = i.USERID and CUSTOMERID=i.CUSTOMERID and g=i.g and ID >= i.ID and ACTION not in ( 'ACSCEVNT', 'NEXTCNSM' ) order by ID desc ) e where i.ACTION not in ( 'ACSCEVNT', 'NEXTCNSM' ) order by i.ID
Eshwar 176 Reputation points2021-11-13T09:15:41.107+00:00 @Viorel
Sorry there are some changes in the requirements again!!
Can you please help?Input:
Expected output:
Requirement:
- Start/End will be with ACSCEVNT/NEXTCNSM
- Start date is datetime of that ACSCEVNT/NEXTCNSM
- End date is datetime of next ACSCEVNT/NEXTCNSM record
- Display all records in between start and end
- If it is end of the day (last events) the end date will be blank for those last record(s)
- Additional display all records where start is not ACSCEVNT/NEXTCNSM with its corresponding start date and end date is blank
- It should be evaluated for each user
Query:
149879-queries.txtViorel 88,571 Reputation points2021-11-16T17:44:52.76+00:00 What do you mean by "These are additional events for 13137"?
Eshwar 176 Reputation points2021-11-16T18:10:47.76+00:00 Thanks a lot @Viorel
So for that customer ID flow there is no start event (ACSCEVNT/NEXTCNSM) so those are orphans and it should be reported with start date as date in that record and end date as null.
FYI.. I have updated sample.Regards,
Eshwar.
Sign in to comment4 additional answers
Sort by: Most helpful
-
Viorel 88,571 Reputation points
2021-11-02T12:12:26.103+00:00 Check a query that uses joins:
select i1.USERID, i2.ACTIONATE, i1.ACTION from @input i1 inner join @input i2 on i2.USERID = i1.USERID and i2.ACTION = 'TEST1' and i2.ACTIONATE < i1.ACTIONATE and cast(i2.ACTIONATE as date) = cast(i1.ACTIONATE as date) left join @input i3 on i3.USERID = i1.USERID and i3.ACTION = 'TEST1' and i3.ACTIONATE < i1.ACTIONATE and cast(i3.ACTIONATE as date) = cast(i1.ACTIONATE as date) and i3.ACTIONATE > i2.ACTIONATE where i1.ACTION not in ( 'TEST1', 'TEST2' ) and i3.ID is null order by USERID, ACTIONATE
-
Eshwar 176 Reputation points
2021-11-08T11:18:55.31+00:00 HI @Viorel ,
Apologies for late response
Solution doesn't work if I replace TEST1 with TEST2 and TEST2 with TEST1 in the input data.
Basically the start pointing can be TEST1 or TEST2 and I need to consider it as new record when TEST1/TEST2 comes.
Also it need not be TEST1, TEST2 my actual values are ACSCEVNT and NEXTCNSM
Thanks,
EshwarViorel 88,571 Reputation points2021-11-08T12:01:10.997+00:00 Did you try to adjust the queries according to your real details? For example, you can use ACTION in ('ACSCEVNT', 'NEXTCNSM') instead of ACTION = 'TEST1'. If it does not work, then maybe give a new example of your current data.
Eshwar 176 Reputation points2021-11-08T12:21:09.967+00:00 Thanks @Viorel ,
Yes I have tried as mentioned it need not be TEST1 as start/end it can TEST2 also based on above data. I tried by replacing TEST1 with TEST2 and TEST2 with TEST1 in the input data and it didn't gave expected results.
Also I need to group on CUSTOMERID as in it should be considered as new/end of the record if action is ACSCEVNT/NEXTCNSM or CUSTOMERID is changed from previous recordRegards,
Eshwar
Sign in to comment
MelissaMa-MSFT 24,131 Reputation points2021-11-03T02:39:08.88+00:00 Hi @Eshwar ,
Please also refer to below:
;with cte as ( select id,userid,ACTIONATE,ACTION, case when ACTION='test' then (ROW_NUMBER() over (partition by userid,ACTION order by id)-1)/2+1 end groupid from (SELECT id,USERID,ACTIONATE,case when ACTION like 'test%' then 'test' else ACTION end ACTION FROM @INPUT) a) ,cte1 as ( select userid,ACTIONATE,ACTION,groupid=max(groupid) over (partition by userid order by c) from ( select *,c= count(groupid) over (partition by userid order by id) from cte ) a) ,cte2 as ( select userid,min(ACTIONATE) over (partition by userid,groupid order by ACTIONATE) ACTIONATE,ACTION,groupid from cte1) select USERID,ACTIONATE,ACTION from cte2 where ACTION<>'test'
Output:
USERID ACTIONATE ACTION 1 2021-01-01 10:30:01.000 ACTION1 1 2021-01-01 10:30:01.000 ACTION2 1 2021-01-01 11:32:02.000 ACTION1 1 2021-01-03 10:30:01.000 ACTION1 1 2021-01-03 10:30:01.000 ACTION2 2 2021-01-01 09:30:01.000 ACTION1 2 2021-01-01 09:30:01.000 ACTION2 2 2021-01-01 09:30:01.000 ACTION3 2 2021-01-01 09:40:02.000 ACTION1 2 2021-01-03 08:30:01.000 ACTION1 2 2021-01-03 08:30:01.000 ACTION2
Best regards,
Melissa
If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".
Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.-
Eshwar 176 Reputation points
2021-11-08T11:22:57.767+00:00 Apologies for late response
Thanks, solution works even if I replace TEST1 with TEST2 and TEST2 with TEST1 in the input data.
Also my actual values are ACSCEVNT and NEXTCNSM, how can I replace them in the query and I need to group on CUSTOMERID as in it should be considered as new/end of the record if action is ACSCEVNT/NEXTCNSM or CUSTOMERID is changed from previous recordAppreciate your inputs!
Thanks,
Eshwar
Sign in to commentViorel 88,571 Reputation points2021-11-08T16:17:44.657+00:00 Check an adjusted query:
select i.USERID, i.CUSTOMERID, s.ACTION_DATE, i.ACTION from @INPUT i cross apply ( select top(1) * from @INPUT where USERID = i.USERID and CUSTOMERID=i.CUSTOMERID and cast(ACTION_DATE as date) = cast(i.ACTION_DATE as date) and ACTION_DATE <= i.ACTION_DATE and ACTION in ( 'ACSCEVNT', 'NEXTCNSM' ) order by ACTION_DATE, ID desc ) s where i.ACTION not in ( 'ACSCEVNT', 'NEXTCNSM' ) order by USERID, ACTION_DATE
Viorel 88,571 Reputation points2021-11-03T08:25:08.837+00:00 Also check an alternative that uses TOP(1):
select i.USERID, s.ACTIONATE, i.ACTION from @INPUT i cross apply ( select top(1) * from @INPUT where USERID = i.USERID and cast(ACTIONATE as date) = cast(i.ACTIONATE as date) and ACTIONATE < i.ACTIONATE and ACTION = 'TEST1' order by ACTIONATE desc ) s where i.ACTION not in ( 'TEST1', 'TEST2' ) order by USERID, ACTIONATE
0 No comments -
-
To include the additional ActionEndDate:
select i.USERID, i.CUSTOMERID, s.ACTION_DATE, e.ACTION_DATE as ActionEndDate, i.ACTION
from @INPUT i
cross apply
(
select top(1) *
from @INPUT
where USERID = i.USERID and CUSTOMERID=i.CUSTOMERID
and cast(ACTION_DATE as date) = cast(i.ACTION_DATE as date)
and ACTION_DATE <= i.ACTION_DATE and ACTION in ( 'ACSCEVNT', 'NEXTCNSM' )
order by ACTION_DATE, ID desc
) s
cross apply
(
select top(1) *
from @INPUT
where USERID = i.USERID and CUSTOMERID=i.CUSTOMERID
and cast(ACTION_DATE as date) = cast(i.ACTION_DATE as date)
and ACTION_DATE >= i.ACTION_DATE and ACTION not in ( 'ACSCEVNT', 'NEXTCNSM' )
order by ACTION_DATE desc, ID desc
) e
where i.ACTION not in ( 'ACSCEVNT', 'NEXTCNSM' )
order by USERID, ACTION_DATE
@Viorel @MelissaMa-MSFT
Some real data added customerid and actionenddate(last record in that flow) in the output:
Input:
Expected Output:
Query:
147491-queries.txt
Hope it make sense!
Thanks a lot for your help!