How to check specific range of values in Array.

The issue that I'm experiencing is that I have an list of dictionary's.
The structure of dictionary's is like

{ date: 03/05/2021,  code: "113", amount: "0", id: 4001 }, - END DELAY

{ date: 01/05/2021,  code: "110", amount: "234", id: 4002 }, - DELAY

{ date: 22/04/2021,  code: "110", amount: "234", id: 4003 }, - START DELAY

{ date: 18/04/2021,  code: "113", amount: "0", id: 4004 }, - END DELAY

{ date: 13/04/2021,  code: "110", amount: "234", id: 4005 }, - DELAY

{ date: 09/04/2021,  code: "115", amount: "0", id: 4006 },

{ date: 03/04/2021,  code: "110", amount: "234", id: 4007 }, - START DELAY

{ date: 18/02/2021,  code: "113", amount: "0", id: 4008 }, - END DELAY

{ date: 22/01/2021,  code: "110", amount: "234", id: 4009 }, - DELAY

{ date: 22/11/2020,  code: "105", amount: "0", id: 4010 },

{ date: 03/05/2020,  code: "103", amount: "0", id: 4011 },

{ date: 13/01/2019,  code: "110", amount: "234", id: 4012 }, - DELAY

{ date: 03/05/2016,  code: "110", amount: "234", id: 4013 }, - DELAY

... and so on.


I need to calculate delays in contract from this between code 113 and code 110 for every range as explained above (colored values).

Event (code) 110 means delay.
Event (code) 113 means the end of the delay.

Before reporting the end of delays (code=113 ), a contract can have more reported events (code) 110 (event is reported at least once a month)
One contract can have different long delays. Within the contract, I need to find the longest delay in 1 year.
I need to find all events (code) 113 in 1 year (365 days) and all related events 110 (the last events 110 is not necessarily to be within 1 year (it can be more than 1 year)

What is the best way to do this? How can I identify the ranges that I will know what is the starting "113" and ending "110". Thx.

  Discussion posts and replies are publicly visible

  • 0
    Certified Lead Developer
    in reply to Darko

    Try yourself and in a few hours if you haven't got it I might give it a try.

  • Just to button up the SQL view solution here, you can certainly add 15 days to each delay and calculate a running delay by utilizing the current date (when no 113 present).

    This adjustment assumes you want the longest delay in each calendar year based on the delay start date, which can be adjusted to end date as well.

    SELECT
    DATEPART(year,[date]) 'delayYear',
    max(daysDelayed) 'delayDays'
    FROM
    (
    	SELECT
    	[id],
    	[date],
    	[code],
    	[amount],
    	[delayEnd],
    	DATEDIFF(
    		day,
    		[date],
    		[delayEnd]
    	)+15 'daysDelayed'
    	FROM
    	(
    		SELECT
    		t.[id],
    		t.[date],
    		t.[code],
    		t.[amount],
    		CASE 
    			WHEN (t.[code]=110) THEN
    				CASE 
    					WHEN EXISTS (select * from chris_test_table t2 where t2.[date]>t.[date] and t2.[code]=113) THEN 
    						(select min(date) from chris_test_table t3 where t3.[date]>t.[date] and t3.[code]=113)
    					ELSE 
    						CAST(GETDATE() AS DATE)
    				END
    			ELSE null
    		END as 'delayEnd'
    		FROM chris_test_table t
    	) a
    )b
    GROUP BY DATEPART(year,b.[date])

    I added a few rows for 2021 code 110's with no ending 113, results for year and longest delay:

  • Thx Chris for this. The time range is -1 year from today that is the date interval to be checked. So -365 days from today. I misplaced this info.  

  • So What I have done is that based on your suggestion is:
    I have created the list of dictionaries as originally described.
    For that list, I have extracted the indexes of code 113,
    I have used those indexes as indices for the new list of lists, and this part is working fine.
    Then I have extracted all 110 of that sublists and also their indexes. I have gotten a Max index of all 110 from all chunks.
    What I should do is to map this but I'm missing something. I have tried but no luck still.
    Did I go in the wrong direction? Thx.

  • No worries, this update pulls only the maximum delay that has ended within the past year.  Change the commenting on the final WHERE clauses to flip to use delays that have started within the past year.  As, a delay could start 14 months ago and end 10 months ago.

    SELECT
    max(daysDelayed) 'delayDays'
    FROM
    (
    	SELECT
    	[id],
    	[date],
    	[code],
    	[amount],
    	[delayEnd],
    	DATEDIFF(
    		day,
    		[date],
    		[delayEnd]
    	)+15 'daysDelayed'
    	FROM
    	(
    		SELECT
    		t.[id],
    		t.[date],
    		t.[code],
    		t.[amount],
    		CASE 
    			WHEN (t.[code]=110) THEN
    				CASE 
    					WHEN EXISTS (select * from chris_test_table t2 where t2.[date]>t.[date] and t2.[code]=113) THEN 
    						(select min(date) from chris_test_table t3 where t3.[date]>t.[date] and t3.[code]=113)
    					ELSE 
    						CAST(GETDATE() AS DATE)
    				END
    			ELSE null
    		END as 'delayEnd'
    		FROM chris_test_table t
    	) a
    	--WHERE a.[date]>=CAST(DATEADD(year,-1,GETDATE()) as DATE) -- Uses delay START
    	WHERE a.[delayEnd]>=CAST(DATEADD(year,-1,GETDATE()) as DATE) -- Uses delay END
    ) b

  • 0
    Certified Lead Developer
    in reply to Darko

    In your case max would be based on the date, so max (index (sublist, "Date"))

  • Thx. But it's the same, as the last index of 110 also has the oldest date? I'm not sure how to write this to map the max 110 and 113 so that I can do the calculations properly?.