ORACLE SQL: Find last minimum and maximum consecutive periodFinding duplicate values in a SQL tableFind all tables containing column with specified name - MS SQL ServerSQL query for last entries in a periodHow to find possible consecutive values and return the minimum and the maximum values of that series?Get minimum and maximum datetime for each row between a date rangeDerive Last PO Price in SQL Query (Oracle)Find consecutive dates spanning a weekendHow to take last two maximum dates from multiple tables OracleMaximum number of consecutive occurrences of a value by group in SQLFind count of consecutive similar values in a column - Oracle

Can the Produce Flame cantrip be used to grapple, or as an unarmed strike, in the right circumstances?

Add an angle to a sphere

Is there a way to make member function NOT callable from constructor?

Is this food a bread or a loaf?

When blogging recipes, how can I support both readers who want the narrative/journey and ones who want the printer-friendly recipe?

Calculate Levenshtein distance between two strings in Python

New order #4: World

Is Fable (1996) connected in any way to the Fable franchise from Lionhead Studios?

How can I add custom success page

Why is the design of haulage companies so “special”?

What to wear for invited talk in Canada

Information to fellow intern about hiring?

Is there a name of the flying bionic bird?

If a centaur druid Wild Shapes into a Giant Elk, do their Charge features stack?

Manga about a female worker who got dragged into another world together with this high school girl and she was just told she's not needed anymore

How can I fix this gap between bookcases I made?

aging parents with no investments

Does bootstrapped regression allow for inference?

Is it wise to focus on putting odd beats on left when playing double bass drums?

Where to refill my bottle in India?

Pristine Bit Checking

Lied on resume at previous job

Is Social Media Science Fiction?

Was there ever an axiom rendered a theorem?



ORACLE SQL: Find last minimum and maximum consecutive period


Finding duplicate values in a SQL tableFind all tables containing column with specified name - MS SQL ServerSQL query for last entries in a periodHow to find possible consecutive values and return the minimum and the maximum values of that series?Get minimum and maximum datetime for each row between a date rangeDerive Last PO Price in SQL Query (Oracle)Find consecutive dates spanning a weekendHow to take last two maximum dates from multiple tables OracleMaximum number of consecutive occurrences of a value by group in SQLFind count of consecutive similar values in a column - Oracle






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty height:90px;width:728px;box-sizing:border-box;








-2















I have the sample data set below which list the water meters not working for specific reason for a certain range period (jan 2016 to december 2018).



sample dataset



I would like to have a query that retrieves the last maximum and minimum consecutive period where the meter was not working within that range of period.



Expected result



any help will be greatly appreciated.










share|improve this question






























    -2















    I have the sample data set below which list the water meters not working for specific reason for a certain range period (jan 2016 to december 2018).



    sample dataset



    I would like to have a query that retrieves the last maximum and minimum consecutive period where the meter was not working within that range of period.



    Expected result



    any help will be greatly appreciated.










    share|improve this question


























      -2












      -2








      -2








      I have the sample data set below which list the water meters not working for specific reason for a certain range period (jan 2016 to december 2018).



      sample dataset



      I would like to have a query that retrieves the last maximum and minimum consecutive period where the meter was not working within that range of period.



      Expected result



      any help will be greatly appreciated.










      share|improve this question
















      I have the sample data set below which list the water meters not working for specific reason for a certain range period (jan 2016 to december 2018).



      sample dataset



      I would like to have a query that retrieves the last maximum and minimum consecutive period where the meter was not working within that range of period.



      Expected result



      any help will be greatly appreciated.







      sql oracle






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Mar 8 at 8:52









      Santhana

      304214




      304214










      asked Mar 8 at 6:56









      Sundeep GanesheSundeep Ganeshe

      62




      62






















          3 Answers
          3






          active

          oldest

          votes


















          1














          You have two options:



          select code, to_char(min_period, 'yyyymm') min_period, to_char(max_period, 'yyyymm') max_period
          from (
          select code, min(period) min_period, max(period) max_period,
          max(min(period)) over (partition by code) max_min_period
          from (
          select code, period, sum(flag) over (partition by code order by period) grp
          from (
          select code, period,
          case when add_months(period, -1)
          = lag(period) over (partition by code order by period)
          then 0 else 1 end flag
          from (select mrdg_acc_code code, to_date(mrdg_per_period, 'yyyymm') period from t)))
          group by code, grp)
          where min_period = max_min_period


          Explanation:



          • flag rows where period is not equal previous period plus one month,

          • create column grp which sums flags consecutively,

          • group data using code and grp additionaly finding maximal start of period,

          • show only rows where min_period = max_min_period

          Second option is recursive CTE available in Oracle 11g and above:



          with 
          data(period, code) as (
          select to_date(mrdg_per_period, 'yyyymm'), mrdg_acc_code from t
          where mrdg_per_period between 201601 and 201812),
          cte (period, code) as (
          select to_char(period, 'yyyymm'), code from data
          where (period, code) in (select max(period), code from data group by code)
          union all
          select to_char(data.period, 'yyyymm'), cte.code
          from cte
          join data on data.code = cte.code
          and data.period = add_months(to_date(cte.period, 'yyyymm'), -1))
          select code, min(period) min_period, max(period) max_period
          from cte group by code


          Explanation:



          • subquery data filters only rows from 2016 - 2018 additionaly converting period to date format. We need this for function add_months to work.


          • cte is recursive. Anchor finds starting rows, these with maximum period for each code. After union all is recursive member, which looks for the row one month older than current. If it finds it then net row, if not then stop.

          • final select groups data. Notice that period which were not consecutive were rejected by cte.

          Though recursive queries are slower than traditional ones, there can be scenarios where second solution is better.



          Here is the dbfiddle demo for both queries. Good luck.






          share|improve this answer























          • thank you Ponder Stibbons :) for the explanation. it works. i am new as dba and have many similar reports to work on. i have now understood the concept and follow same for other reports. thank you a lot.

            – Sundeep Ganeshe
            Mar 13 at 5:40



















          1














          use aggregate function with group by



          select max(mdrg_per_period) mdrg_per_period, mrdg_acc_code,max(mrdg_date_read),rea_Desc,min(mdrg_per_period) not_working_as_from
          from tablename
          group by mrdg_acc_code,rea_Desc





          share|improve this answer























          • hi fa06, i did try same but could not get the desired result. for example for account 010100010 what i got every time for the minimum period is 201601 but it should be 201610 the last minimum period

            – Sundeep Ganeshe
            Mar 8 at 7:17


















          0














          This is a bit tricky. This is a gap-and-islands problem. To get all continuous periods, it will help if you have an enumeration of months. So, convert the period to a number of months and then subtract a sequence generated using row_number(). The difference is constant for a group of adjacent months.



          This looks like:



          select acc_code, min(period), max(period)
          from (select t.*,
          row_number() over (partition by acc_code order by period_num) as seqnum
          from (select t.*, floor(period / 100) * 12 + mod(period, 100) as period_num
          from t
          ) t
          where rea_desc = 'METER NOT WORKING'
          ) t
          group by (period_num - seqnum);


          Then, if you want the last one for each account, you can use a subquery:



          select t.*
          from (select acc_code, min(period), max(period),
          row_number() over (partition by acc_code order by max(period desc) as seqnum
          from (select t.*,
          row_number() over (partition by acc_code order by period_num) as seqnum
          from (select t.*, floor(period / 100) * 12 + mod(period, 100) as period_num
          from t
          ) t
          where rea_desc = 'METER NOT WORKING'
          ) t
          group by (period_num - seqnum)
          ) t
          where seqnum = 1;





          share|improve this answer























            Your Answer






            StackExchange.ifUsing("editor", function ()
            StackExchange.using("externalEditor", function ()
            StackExchange.using("snippets", function ()
            StackExchange.snippets.init();
            );
            );
            , "code-snippets");

            StackExchange.ready(function()
            var channelOptions =
            tags: "".split(" "),
            id: "1"
            ;
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function()
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled)
            StackExchange.using("snippets", function()
            createEditor();
            );

            else
            createEditor();

            );

            function createEditor()
            StackExchange.prepareEditor(
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            imageUploader:
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            ,
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            );



            );













            draft saved

            draft discarded


















            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55058191%2foracle-sql-find-last-minimum-and-maximum-consecutive-period%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown

























            3 Answers
            3






            active

            oldest

            votes








            3 Answers
            3






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            1














            You have two options:



            select code, to_char(min_period, 'yyyymm') min_period, to_char(max_period, 'yyyymm') max_period
            from (
            select code, min(period) min_period, max(period) max_period,
            max(min(period)) over (partition by code) max_min_period
            from (
            select code, period, sum(flag) over (partition by code order by period) grp
            from (
            select code, period,
            case when add_months(period, -1)
            = lag(period) over (partition by code order by period)
            then 0 else 1 end flag
            from (select mrdg_acc_code code, to_date(mrdg_per_period, 'yyyymm') period from t)))
            group by code, grp)
            where min_period = max_min_period


            Explanation:



            • flag rows where period is not equal previous period plus one month,

            • create column grp which sums flags consecutively,

            • group data using code and grp additionaly finding maximal start of period,

            • show only rows where min_period = max_min_period

            Second option is recursive CTE available in Oracle 11g and above:



            with 
            data(period, code) as (
            select to_date(mrdg_per_period, 'yyyymm'), mrdg_acc_code from t
            where mrdg_per_period between 201601 and 201812),
            cte (period, code) as (
            select to_char(period, 'yyyymm'), code from data
            where (period, code) in (select max(period), code from data group by code)
            union all
            select to_char(data.period, 'yyyymm'), cte.code
            from cte
            join data on data.code = cte.code
            and data.period = add_months(to_date(cte.period, 'yyyymm'), -1))
            select code, min(period) min_period, max(period) max_period
            from cte group by code


            Explanation:



            • subquery data filters only rows from 2016 - 2018 additionaly converting period to date format. We need this for function add_months to work.


            • cte is recursive. Anchor finds starting rows, these with maximum period for each code. After union all is recursive member, which looks for the row one month older than current. If it finds it then net row, if not then stop.

            • final select groups data. Notice that period which were not consecutive were rejected by cte.

            Though recursive queries are slower than traditional ones, there can be scenarios where second solution is better.



            Here is the dbfiddle demo for both queries. Good luck.






            share|improve this answer























            • thank you Ponder Stibbons :) for the explanation. it works. i am new as dba and have many similar reports to work on. i have now understood the concept and follow same for other reports. thank you a lot.

              – Sundeep Ganeshe
              Mar 13 at 5:40
















            1














            You have two options:



            select code, to_char(min_period, 'yyyymm') min_period, to_char(max_period, 'yyyymm') max_period
            from (
            select code, min(period) min_period, max(period) max_period,
            max(min(period)) over (partition by code) max_min_period
            from (
            select code, period, sum(flag) over (partition by code order by period) grp
            from (
            select code, period,
            case when add_months(period, -1)
            = lag(period) over (partition by code order by period)
            then 0 else 1 end flag
            from (select mrdg_acc_code code, to_date(mrdg_per_period, 'yyyymm') period from t)))
            group by code, grp)
            where min_period = max_min_period


            Explanation:



            • flag rows where period is not equal previous period plus one month,

            • create column grp which sums flags consecutively,

            • group data using code and grp additionaly finding maximal start of period,

            • show only rows where min_period = max_min_period

            Second option is recursive CTE available in Oracle 11g and above:



            with 
            data(period, code) as (
            select to_date(mrdg_per_period, 'yyyymm'), mrdg_acc_code from t
            where mrdg_per_period between 201601 and 201812),
            cte (period, code) as (
            select to_char(period, 'yyyymm'), code from data
            where (period, code) in (select max(period), code from data group by code)
            union all
            select to_char(data.period, 'yyyymm'), cte.code
            from cte
            join data on data.code = cte.code
            and data.period = add_months(to_date(cte.period, 'yyyymm'), -1))
            select code, min(period) min_period, max(period) max_period
            from cte group by code


            Explanation:



            • subquery data filters only rows from 2016 - 2018 additionaly converting period to date format. We need this for function add_months to work.


            • cte is recursive. Anchor finds starting rows, these with maximum period for each code. After union all is recursive member, which looks for the row one month older than current. If it finds it then net row, if not then stop.

            • final select groups data. Notice that period which were not consecutive were rejected by cte.

            Though recursive queries are slower than traditional ones, there can be scenarios where second solution is better.



            Here is the dbfiddle demo for both queries. Good luck.






            share|improve this answer























            • thank you Ponder Stibbons :) for the explanation. it works. i am new as dba and have many similar reports to work on. i have now understood the concept and follow same for other reports. thank you a lot.

              – Sundeep Ganeshe
              Mar 13 at 5:40














            1












            1








            1







            You have two options:



            select code, to_char(min_period, 'yyyymm') min_period, to_char(max_period, 'yyyymm') max_period
            from (
            select code, min(period) min_period, max(period) max_period,
            max(min(period)) over (partition by code) max_min_period
            from (
            select code, period, sum(flag) over (partition by code order by period) grp
            from (
            select code, period,
            case when add_months(period, -1)
            = lag(period) over (partition by code order by period)
            then 0 else 1 end flag
            from (select mrdg_acc_code code, to_date(mrdg_per_period, 'yyyymm') period from t)))
            group by code, grp)
            where min_period = max_min_period


            Explanation:



            • flag rows where period is not equal previous period plus one month,

            • create column grp which sums flags consecutively,

            • group data using code and grp additionaly finding maximal start of period,

            • show only rows where min_period = max_min_period

            Second option is recursive CTE available in Oracle 11g and above:



            with 
            data(period, code) as (
            select to_date(mrdg_per_period, 'yyyymm'), mrdg_acc_code from t
            where mrdg_per_period between 201601 and 201812),
            cte (period, code) as (
            select to_char(period, 'yyyymm'), code from data
            where (period, code) in (select max(period), code from data group by code)
            union all
            select to_char(data.period, 'yyyymm'), cte.code
            from cte
            join data on data.code = cte.code
            and data.period = add_months(to_date(cte.period, 'yyyymm'), -1))
            select code, min(period) min_period, max(period) max_period
            from cte group by code


            Explanation:



            • subquery data filters only rows from 2016 - 2018 additionaly converting period to date format. We need this for function add_months to work.


            • cte is recursive. Anchor finds starting rows, these with maximum period for each code. After union all is recursive member, which looks for the row one month older than current. If it finds it then net row, if not then stop.

            • final select groups data. Notice that period which were not consecutive were rejected by cte.

            Though recursive queries are slower than traditional ones, there can be scenarios where second solution is better.



            Here is the dbfiddle demo for both queries. Good luck.






            share|improve this answer













            You have two options:



            select code, to_char(min_period, 'yyyymm') min_period, to_char(max_period, 'yyyymm') max_period
            from (
            select code, min(period) min_period, max(period) max_period,
            max(min(period)) over (partition by code) max_min_period
            from (
            select code, period, sum(flag) over (partition by code order by period) grp
            from (
            select code, period,
            case when add_months(period, -1)
            = lag(period) over (partition by code order by period)
            then 0 else 1 end flag
            from (select mrdg_acc_code code, to_date(mrdg_per_period, 'yyyymm') period from t)))
            group by code, grp)
            where min_period = max_min_period


            Explanation:



            • flag rows where period is not equal previous period plus one month,

            • create column grp which sums flags consecutively,

            • group data using code and grp additionaly finding maximal start of period,

            • show only rows where min_period = max_min_period

            Second option is recursive CTE available in Oracle 11g and above:



            with 
            data(period, code) as (
            select to_date(mrdg_per_period, 'yyyymm'), mrdg_acc_code from t
            where mrdg_per_period between 201601 and 201812),
            cte (period, code) as (
            select to_char(period, 'yyyymm'), code from data
            where (period, code) in (select max(period), code from data group by code)
            union all
            select to_char(data.period, 'yyyymm'), cte.code
            from cte
            join data on data.code = cte.code
            and data.period = add_months(to_date(cte.period, 'yyyymm'), -1))
            select code, min(period) min_period, max(period) max_period
            from cte group by code


            Explanation:



            • subquery data filters only rows from 2016 - 2018 additionaly converting period to date format. We need this for function add_months to work.


            • cte is recursive. Anchor finds starting rows, these with maximum period for each code. After union all is recursive member, which looks for the row one month older than current. If it finds it then net row, if not then stop.

            • final select groups data. Notice that period which were not consecutive were rejected by cte.

            Though recursive queries are slower than traditional ones, there can be scenarios where second solution is better.



            Here is the dbfiddle demo for both queries. Good luck.







            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Mar 8 at 14:29









            Ponder StibbonsPonder Stibbons

            9,10421519




            9,10421519












            • thank you Ponder Stibbons :) for the explanation. it works. i am new as dba and have many similar reports to work on. i have now understood the concept and follow same for other reports. thank you a lot.

              – Sundeep Ganeshe
              Mar 13 at 5:40


















            • thank you Ponder Stibbons :) for the explanation. it works. i am new as dba and have many similar reports to work on. i have now understood the concept and follow same for other reports. thank you a lot.

              – Sundeep Ganeshe
              Mar 13 at 5:40

















            thank you Ponder Stibbons :) for the explanation. it works. i am new as dba and have many similar reports to work on. i have now understood the concept and follow same for other reports. thank you a lot.

            – Sundeep Ganeshe
            Mar 13 at 5:40






            thank you Ponder Stibbons :) for the explanation. it works. i am new as dba and have many similar reports to work on. i have now understood the concept and follow same for other reports. thank you a lot.

            – Sundeep Ganeshe
            Mar 13 at 5:40














            1














            use aggregate function with group by



            select max(mdrg_per_period) mdrg_per_period, mrdg_acc_code,max(mrdg_date_read),rea_Desc,min(mdrg_per_period) not_working_as_from
            from tablename
            group by mrdg_acc_code,rea_Desc





            share|improve this answer























            • hi fa06, i did try same but could not get the desired result. for example for account 010100010 what i got every time for the minimum period is 201601 but it should be 201610 the last minimum period

              – Sundeep Ganeshe
              Mar 8 at 7:17















            1














            use aggregate function with group by



            select max(mdrg_per_period) mdrg_per_period, mrdg_acc_code,max(mrdg_date_read),rea_Desc,min(mdrg_per_period) not_working_as_from
            from tablename
            group by mrdg_acc_code,rea_Desc





            share|improve this answer























            • hi fa06, i did try same but could not get the desired result. for example for account 010100010 what i got every time for the minimum period is 201601 but it should be 201610 the last minimum period

              – Sundeep Ganeshe
              Mar 8 at 7:17













            1












            1








            1







            use aggregate function with group by



            select max(mdrg_per_period) mdrg_per_period, mrdg_acc_code,max(mrdg_date_read),rea_Desc,min(mdrg_per_period) not_working_as_from
            from tablename
            group by mrdg_acc_code,rea_Desc





            share|improve this answer













            use aggregate function with group by



            select max(mdrg_per_period) mdrg_per_period, mrdg_acc_code,max(mrdg_date_read),rea_Desc,min(mdrg_per_period) not_working_as_from
            from tablename
            group by mrdg_acc_code,rea_Desc






            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Mar 8 at 6:58









            fa06fa06

            18.9k21019




            18.9k21019












            • hi fa06, i did try same but could not get the desired result. for example for account 010100010 what i got every time for the minimum period is 201601 but it should be 201610 the last minimum period

              – Sundeep Ganeshe
              Mar 8 at 7:17

















            • hi fa06, i did try same but could not get the desired result. for example for account 010100010 what i got every time for the minimum period is 201601 but it should be 201610 the last minimum period

              – Sundeep Ganeshe
              Mar 8 at 7:17
















            hi fa06, i did try same but could not get the desired result. for example for account 010100010 what i got every time for the minimum period is 201601 but it should be 201610 the last minimum period

            – Sundeep Ganeshe
            Mar 8 at 7:17





            hi fa06, i did try same but could not get the desired result. for example for account 010100010 what i got every time for the minimum period is 201601 but it should be 201610 the last minimum period

            – Sundeep Ganeshe
            Mar 8 at 7:17











            0














            This is a bit tricky. This is a gap-and-islands problem. To get all continuous periods, it will help if you have an enumeration of months. So, convert the period to a number of months and then subtract a sequence generated using row_number(). The difference is constant for a group of adjacent months.



            This looks like:



            select acc_code, min(period), max(period)
            from (select t.*,
            row_number() over (partition by acc_code order by period_num) as seqnum
            from (select t.*, floor(period / 100) * 12 + mod(period, 100) as period_num
            from t
            ) t
            where rea_desc = 'METER NOT WORKING'
            ) t
            group by (period_num - seqnum);


            Then, if you want the last one for each account, you can use a subquery:



            select t.*
            from (select acc_code, min(period), max(period),
            row_number() over (partition by acc_code order by max(period desc) as seqnum
            from (select t.*,
            row_number() over (partition by acc_code order by period_num) as seqnum
            from (select t.*, floor(period / 100) * 12 + mod(period, 100) as period_num
            from t
            ) t
            where rea_desc = 'METER NOT WORKING'
            ) t
            group by (period_num - seqnum)
            ) t
            where seqnum = 1;





            share|improve this answer



























              0














              This is a bit tricky. This is a gap-and-islands problem. To get all continuous periods, it will help if you have an enumeration of months. So, convert the period to a number of months and then subtract a sequence generated using row_number(). The difference is constant for a group of adjacent months.



              This looks like:



              select acc_code, min(period), max(period)
              from (select t.*,
              row_number() over (partition by acc_code order by period_num) as seqnum
              from (select t.*, floor(period / 100) * 12 + mod(period, 100) as period_num
              from t
              ) t
              where rea_desc = 'METER NOT WORKING'
              ) t
              group by (period_num - seqnum);


              Then, if you want the last one for each account, you can use a subquery:



              select t.*
              from (select acc_code, min(period), max(period),
              row_number() over (partition by acc_code order by max(period desc) as seqnum
              from (select t.*,
              row_number() over (partition by acc_code order by period_num) as seqnum
              from (select t.*, floor(period / 100) * 12 + mod(period, 100) as period_num
              from t
              ) t
              where rea_desc = 'METER NOT WORKING'
              ) t
              group by (period_num - seqnum)
              ) t
              where seqnum = 1;





              share|improve this answer

























                0












                0








                0







                This is a bit tricky. This is a gap-and-islands problem. To get all continuous periods, it will help if you have an enumeration of months. So, convert the period to a number of months and then subtract a sequence generated using row_number(). The difference is constant for a group of adjacent months.



                This looks like:



                select acc_code, min(period), max(period)
                from (select t.*,
                row_number() over (partition by acc_code order by period_num) as seqnum
                from (select t.*, floor(period / 100) * 12 + mod(period, 100) as period_num
                from t
                ) t
                where rea_desc = 'METER NOT WORKING'
                ) t
                group by (period_num - seqnum);


                Then, if you want the last one for each account, you can use a subquery:



                select t.*
                from (select acc_code, min(period), max(period),
                row_number() over (partition by acc_code order by max(period desc) as seqnum
                from (select t.*,
                row_number() over (partition by acc_code order by period_num) as seqnum
                from (select t.*, floor(period / 100) * 12 + mod(period, 100) as period_num
                from t
                ) t
                where rea_desc = 'METER NOT WORKING'
                ) t
                group by (period_num - seqnum)
                ) t
                where seqnum = 1;





                share|improve this answer













                This is a bit tricky. This is a gap-and-islands problem. To get all continuous periods, it will help if you have an enumeration of months. So, convert the period to a number of months and then subtract a sequence generated using row_number(). The difference is constant for a group of adjacent months.



                This looks like:



                select acc_code, min(period), max(period)
                from (select t.*,
                row_number() over (partition by acc_code order by period_num) as seqnum
                from (select t.*, floor(period / 100) * 12 + mod(period, 100) as period_num
                from t
                ) t
                where rea_desc = 'METER NOT WORKING'
                ) t
                group by (period_num - seqnum);


                Then, if you want the last one for each account, you can use a subquery:



                select t.*
                from (select acc_code, min(period), max(period),
                row_number() over (partition by acc_code order by max(period desc) as seqnum
                from (select t.*,
                row_number() over (partition by acc_code order by period_num) as seqnum
                from (select t.*, floor(period / 100) * 12 + mod(period, 100) as period_num
                from t
                ) t
                where rea_desc = 'METER NOT WORKING'
                ) t
                group by (period_num - seqnum)
                ) t
                where seqnum = 1;






                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Mar 8 at 13:09









                Gordon LinoffGordon Linoff

                795k37318423




                795k37318423



























                    draft saved

                    draft discarded
















































                    Thanks for contributing an answer to Stack Overflow!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid


                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.

                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function ()
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55058191%2foracle-sql-find-last-minimum-and-maximum-consecutive-period%23new-answer', 'question_page');

                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    1928 у кіно

                    Захаров Федір Захарович

                    Ель Греко