T-SQL Identifying gaps in broken sequence of dates





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







2















Please can you help with a problem I am having, I believe is related to the gaps and islands problem in T-SQL. I am using SQL Server 2014.



I am trying to identify count the number of consecutive occurrences of a table/index combination using a date column to distinguish between the broken chains.



Please see the below T-SQL to demonstrate what I am trying to achieve, in particular how do I calculate the Rnk column which for demo purposes I have manually hard-coded?



CREATE TABLE #test (RowID INT IDENTITY(1,1), FileDate DATE, TableName VARCHAR(100), IndexName VARCHAR(100), Rnk INT)

INSERT INTO #test (FileDate, TableName, IndexName, Rnk)
VALUES
('2015-10-31', 't1', 'idx1', 1),
('2015-10-30', 't1', 'idx1', 2),

('2015-10-27', 't1', 'idx1', 1),
('2015-10-26', 't1', 'idx1', 2),
('2015-10-25', 't1', 'idx1', 3),

('2015-10-23', 't1', 'idx1', 1),
('2015-10-22', 't1', 'idx1', 2),
('2015-10-21', 't1', 'idx1', 3),
('2015-10-20', 't1', 'idx1', 4),
('2015-10-19', 't1', 'idx1', 5),
('2015-10-15', 't1', 'idx1', 1),
('2015-10-13', 't1', 'idx1', 1),
('2015-10-10', 't1', 'idx1', 1),
('2015-10-09', 't1', 'idx1', 2),

('2015-10-27', 't3', 'idx13', 1),
('2015-10-26', 't3', 'idx13', 2),
('2015-10-25', 't3', 'idx15', 1),
('2015-10-24', 't3', 'idx15', 2),
('2015-10-21', 't3', 'idx13', 1)

SELECT * FROM #test

DROP TABLE #test


In the screenshot I've attached, the portion of results highlighted would show I want the Rnk column to sequence the consecutive appearance of t1/idx between 2015-10-27 - 2015-10-25, but reset the number for the next appearance at 2015-10-23 through to 2015-10-19.



Can anyone assist me please?



IMG1



Thanks.










share|improve this question































    2















    Please can you help with a problem I am having, I believe is related to the gaps and islands problem in T-SQL. I am using SQL Server 2014.



    I am trying to identify count the number of consecutive occurrences of a table/index combination using a date column to distinguish between the broken chains.



    Please see the below T-SQL to demonstrate what I am trying to achieve, in particular how do I calculate the Rnk column which for demo purposes I have manually hard-coded?



    CREATE TABLE #test (RowID INT IDENTITY(1,1), FileDate DATE, TableName VARCHAR(100), IndexName VARCHAR(100), Rnk INT)

    INSERT INTO #test (FileDate, TableName, IndexName, Rnk)
    VALUES
    ('2015-10-31', 't1', 'idx1', 1),
    ('2015-10-30', 't1', 'idx1', 2),

    ('2015-10-27', 't1', 'idx1', 1),
    ('2015-10-26', 't1', 'idx1', 2),
    ('2015-10-25', 't1', 'idx1', 3),

    ('2015-10-23', 't1', 'idx1', 1),
    ('2015-10-22', 't1', 'idx1', 2),
    ('2015-10-21', 't1', 'idx1', 3),
    ('2015-10-20', 't1', 'idx1', 4),
    ('2015-10-19', 't1', 'idx1', 5),
    ('2015-10-15', 't1', 'idx1', 1),
    ('2015-10-13', 't1', 'idx1', 1),
    ('2015-10-10', 't1', 'idx1', 1),
    ('2015-10-09', 't1', 'idx1', 2),

    ('2015-10-27', 't3', 'idx13', 1),
    ('2015-10-26', 't3', 'idx13', 2),
    ('2015-10-25', 't3', 'idx15', 1),
    ('2015-10-24', 't3', 'idx15', 2),
    ('2015-10-21', 't3', 'idx13', 1)

    SELECT * FROM #test

    DROP TABLE #test


    In the screenshot I've attached, the portion of results highlighted would show I want the Rnk column to sequence the consecutive appearance of t1/idx between 2015-10-27 - 2015-10-25, but reset the number for the next appearance at 2015-10-23 through to 2015-10-19.



    Can anyone assist me please?



    IMG1



    Thanks.










    share|improve this question



























      2












      2








      2


      0






      Please can you help with a problem I am having, I believe is related to the gaps and islands problem in T-SQL. I am using SQL Server 2014.



      I am trying to identify count the number of consecutive occurrences of a table/index combination using a date column to distinguish between the broken chains.



      Please see the below T-SQL to demonstrate what I am trying to achieve, in particular how do I calculate the Rnk column which for demo purposes I have manually hard-coded?



      CREATE TABLE #test (RowID INT IDENTITY(1,1), FileDate DATE, TableName VARCHAR(100), IndexName VARCHAR(100), Rnk INT)

      INSERT INTO #test (FileDate, TableName, IndexName, Rnk)
      VALUES
      ('2015-10-31', 't1', 'idx1', 1),
      ('2015-10-30', 't1', 'idx1', 2),

      ('2015-10-27', 't1', 'idx1', 1),
      ('2015-10-26', 't1', 'idx1', 2),
      ('2015-10-25', 't1', 'idx1', 3),

      ('2015-10-23', 't1', 'idx1', 1),
      ('2015-10-22', 't1', 'idx1', 2),
      ('2015-10-21', 't1', 'idx1', 3),
      ('2015-10-20', 't1', 'idx1', 4),
      ('2015-10-19', 't1', 'idx1', 5),
      ('2015-10-15', 't1', 'idx1', 1),
      ('2015-10-13', 't1', 'idx1', 1),
      ('2015-10-10', 't1', 'idx1', 1),
      ('2015-10-09', 't1', 'idx1', 2),

      ('2015-10-27', 't3', 'idx13', 1),
      ('2015-10-26', 't3', 'idx13', 2),
      ('2015-10-25', 't3', 'idx15', 1),
      ('2015-10-24', 't3', 'idx15', 2),
      ('2015-10-21', 't3', 'idx13', 1)

      SELECT * FROM #test

      DROP TABLE #test


      In the screenshot I've attached, the portion of results highlighted would show I want the Rnk column to sequence the consecutive appearance of t1/idx between 2015-10-27 - 2015-10-25, but reset the number for the next appearance at 2015-10-23 through to 2015-10-19.



      Can anyone assist me please?



      IMG1



      Thanks.










      share|improve this question
















      Please can you help with a problem I am having, I believe is related to the gaps and islands problem in T-SQL. I am using SQL Server 2014.



      I am trying to identify count the number of consecutive occurrences of a table/index combination using a date column to distinguish between the broken chains.



      Please see the below T-SQL to demonstrate what I am trying to achieve, in particular how do I calculate the Rnk column which for demo purposes I have manually hard-coded?



      CREATE TABLE #test (RowID INT IDENTITY(1,1), FileDate DATE, TableName VARCHAR(100), IndexName VARCHAR(100), Rnk INT)

      INSERT INTO #test (FileDate, TableName, IndexName, Rnk)
      VALUES
      ('2015-10-31', 't1', 'idx1', 1),
      ('2015-10-30', 't1', 'idx1', 2),

      ('2015-10-27', 't1', 'idx1', 1),
      ('2015-10-26', 't1', 'idx1', 2),
      ('2015-10-25', 't1', 'idx1', 3),

      ('2015-10-23', 't1', 'idx1', 1),
      ('2015-10-22', 't1', 'idx1', 2),
      ('2015-10-21', 't1', 'idx1', 3),
      ('2015-10-20', 't1', 'idx1', 4),
      ('2015-10-19', 't1', 'idx1', 5),
      ('2015-10-15', 't1', 'idx1', 1),
      ('2015-10-13', 't1', 'idx1', 1),
      ('2015-10-10', 't1', 'idx1', 1),
      ('2015-10-09', 't1', 'idx1', 2),

      ('2015-10-27', 't3', 'idx13', 1),
      ('2015-10-26', 't3', 'idx13', 2),
      ('2015-10-25', 't3', 'idx15', 1),
      ('2015-10-24', 't3', 'idx15', 2),
      ('2015-10-21', 't3', 'idx13', 1)

      SELECT * FROM #test

      DROP TABLE #test


      In the screenshot I've attached, the portion of results highlighted would show I want the Rnk column to sequence the consecutive appearance of t1/idx between 2015-10-27 - 2015-10-25, but reset the number for the next appearance at 2015-10-23 through to 2015-10-19.



      Can anyone assist me please?



      IMG1



      Thanks.







      sql-server tsql sequence gaps-and-islands






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 16 '18 at 17:52









      marc_s

      585k13011261272




      585k13011261272










      asked Nov 16 '18 at 17:27









      user2032414user2032414

      183




      183
























          3 Answers
          3






          active

          oldest

          votes


















          3














          Subtract a sequence of numbers from the date -- and the groups you have identified will have a constant value. Then you can use row_number():



          select t.*,
          row_number() over (partition by tablename, indexname,
          dateadd(day, - seqnum, filedate)
          order by filedate desc
          ) as rnk
          from (select t.*,
          row_number() over (partition by tablename, indexname order by filedate) as seqnum
          from t
          ) t





          share|improve this answer
























          • Thanks very much. That solved it!!

            – user2032414
            Nov 16 '18 at 18:31



















          0














          I would use cumulative approach :



          select t.FileDate, t.TableName, t.IndexName,
          row_number() over (partition by tablename, indexname, grp order by rowid)
          from (select t.*, sum(case when gap > 1 then 1 else 0 end) over (partition by tablename, indexname order by rowid) as grp
          from (select t.*,
          isnull(datediff(day, filedate, lag(filedate) over (partition by tablename, indexname order by rowid)), 1) as gap
          from #test t
          ) t
          ) t;





          share|improve this answer
























          • Thanks, I'll try this approach when I am back in the office.

            – user2032414
            Nov 16 '18 at 18:32



















          0














          Similar to the answer from Yogesh, who beat me to it.

          (hint: don't expect to be faster when typing an answer on your phone)



          SELECT 
          RowID, FileDate, TableName, IndexName,
          ROW_NUMBER() OVER (PARTITION BY TableName, IndexName, DateRank ORDER BY FileDate DESC) AS Rnk
          FROM
          (
          SELECT *,
          SUM(DateGap) OVER (PARTITION BY TableName, IndexName ORDER BY FileDate DESC) AS DateRank
          FROM
          (
          SELECT RowID, FileDate, TableName, IndexName,
          -- Rnk as ExpRnk,
          CASE WHEN DATEDIFF(DAY, FileDate, LAG(FileDate) OVER (PARTITION BY TableName, IndexName ORDER BY FileDate DESC)) <= 1 THEN 0 ELSE 1 END AS DateGap
          FROM #Test
          ) q1
          ) q2
          ORDER BY RowID;





          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%2f53342692%2ft-sql-identifying-gaps-in-broken-sequence-of-dates%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









            3














            Subtract a sequence of numbers from the date -- and the groups you have identified will have a constant value. Then you can use row_number():



            select t.*,
            row_number() over (partition by tablename, indexname,
            dateadd(day, - seqnum, filedate)
            order by filedate desc
            ) as rnk
            from (select t.*,
            row_number() over (partition by tablename, indexname order by filedate) as seqnum
            from t
            ) t





            share|improve this answer
























            • Thanks very much. That solved it!!

              – user2032414
              Nov 16 '18 at 18:31
















            3














            Subtract a sequence of numbers from the date -- and the groups you have identified will have a constant value. Then you can use row_number():



            select t.*,
            row_number() over (partition by tablename, indexname,
            dateadd(day, - seqnum, filedate)
            order by filedate desc
            ) as rnk
            from (select t.*,
            row_number() over (partition by tablename, indexname order by filedate) as seqnum
            from t
            ) t





            share|improve this answer
























            • Thanks very much. That solved it!!

              – user2032414
              Nov 16 '18 at 18:31














            3












            3








            3







            Subtract a sequence of numbers from the date -- and the groups you have identified will have a constant value. Then you can use row_number():



            select t.*,
            row_number() over (partition by tablename, indexname,
            dateadd(day, - seqnum, filedate)
            order by filedate desc
            ) as rnk
            from (select t.*,
            row_number() over (partition by tablename, indexname order by filedate) as seqnum
            from t
            ) t





            share|improve this answer













            Subtract a sequence of numbers from the date -- and the groups you have identified will have a constant value. Then you can use row_number():



            select t.*,
            row_number() over (partition by tablename, indexname,
            dateadd(day, - seqnum, filedate)
            order by filedate desc
            ) as rnk
            from (select t.*,
            row_number() over (partition by tablename, indexname order by filedate) as seqnum
            from t
            ) t






            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Nov 16 '18 at 17:36









            Gordon LinoffGordon Linoff

            797k37318423




            797k37318423













            • Thanks very much. That solved it!!

              – user2032414
              Nov 16 '18 at 18:31



















            • Thanks very much. That solved it!!

              – user2032414
              Nov 16 '18 at 18:31

















            Thanks very much. That solved it!!

            – user2032414
            Nov 16 '18 at 18:31





            Thanks very much. That solved it!!

            – user2032414
            Nov 16 '18 at 18:31













            0














            I would use cumulative approach :



            select t.FileDate, t.TableName, t.IndexName,
            row_number() over (partition by tablename, indexname, grp order by rowid)
            from (select t.*, sum(case when gap > 1 then 1 else 0 end) over (partition by tablename, indexname order by rowid) as grp
            from (select t.*,
            isnull(datediff(day, filedate, lag(filedate) over (partition by tablename, indexname order by rowid)), 1) as gap
            from #test t
            ) t
            ) t;





            share|improve this answer
























            • Thanks, I'll try this approach when I am back in the office.

              – user2032414
              Nov 16 '18 at 18:32
















            0














            I would use cumulative approach :



            select t.FileDate, t.TableName, t.IndexName,
            row_number() over (partition by tablename, indexname, grp order by rowid)
            from (select t.*, sum(case when gap > 1 then 1 else 0 end) over (partition by tablename, indexname order by rowid) as grp
            from (select t.*,
            isnull(datediff(day, filedate, lag(filedate) over (partition by tablename, indexname order by rowid)), 1) as gap
            from #test t
            ) t
            ) t;





            share|improve this answer
























            • Thanks, I'll try this approach when I am back in the office.

              – user2032414
              Nov 16 '18 at 18:32














            0












            0








            0







            I would use cumulative approach :



            select t.FileDate, t.TableName, t.IndexName,
            row_number() over (partition by tablename, indexname, grp order by rowid)
            from (select t.*, sum(case when gap > 1 then 1 else 0 end) over (partition by tablename, indexname order by rowid) as grp
            from (select t.*,
            isnull(datediff(day, filedate, lag(filedate) over (partition by tablename, indexname order by rowid)), 1) as gap
            from #test t
            ) t
            ) t;





            share|improve this answer













            I would use cumulative approach :



            select t.FileDate, t.TableName, t.IndexName,
            row_number() over (partition by tablename, indexname, grp order by rowid)
            from (select t.*, sum(case when gap > 1 then 1 else 0 end) over (partition by tablename, indexname order by rowid) as grp
            from (select t.*,
            isnull(datediff(day, filedate, lag(filedate) over (partition by tablename, indexname order by rowid)), 1) as gap
            from #test t
            ) t
            ) t;






            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Nov 16 '18 at 17:36









            Yogesh SharmaYogesh Sharma

            35k51440




            35k51440













            • Thanks, I'll try this approach when I am back in the office.

              – user2032414
              Nov 16 '18 at 18:32



















            • Thanks, I'll try this approach when I am back in the office.

              – user2032414
              Nov 16 '18 at 18:32

















            Thanks, I'll try this approach when I am back in the office.

            – user2032414
            Nov 16 '18 at 18:32





            Thanks, I'll try this approach when I am back in the office.

            – user2032414
            Nov 16 '18 at 18:32











            0














            Similar to the answer from Yogesh, who beat me to it.

            (hint: don't expect to be faster when typing an answer on your phone)



            SELECT 
            RowID, FileDate, TableName, IndexName,
            ROW_NUMBER() OVER (PARTITION BY TableName, IndexName, DateRank ORDER BY FileDate DESC) AS Rnk
            FROM
            (
            SELECT *,
            SUM(DateGap) OVER (PARTITION BY TableName, IndexName ORDER BY FileDate DESC) AS DateRank
            FROM
            (
            SELECT RowID, FileDate, TableName, IndexName,
            -- Rnk as ExpRnk,
            CASE WHEN DATEDIFF(DAY, FileDate, LAG(FileDate) OVER (PARTITION BY TableName, IndexName ORDER BY FileDate DESC)) <= 1 THEN 0 ELSE 1 END AS DateGap
            FROM #Test
            ) q1
            ) q2
            ORDER BY RowID;





            share|improve this answer




























              0














              Similar to the answer from Yogesh, who beat me to it.

              (hint: don't expect to be faster when typing an answer on your phone)



              SELECT 
              RowID, FileDate, TableName, IndexName,
              ROW_NUMBER() OVER (PARTITION BY TableName, IndexName, DateRank ORDER BY FileDate DESC) AS Rnk
              FROM
              (
              SELECT *,
              SUM(DateGap) OVER (PARTITION BY TableName, IndexName ORDER BY FileDate DESC) AS DateRank
              FROM
              (
              SELECT RowID, FileDate, TableName, IndexName,
              -- Rnk as ExpRnk,
              CASE WHEN DATEDIFF(DAY, FileDate, LAG(FileDate) OVER (PARTITION BY TableName, IndexName ORDER BY FileDate DESC)) <= 1 THEN 0 ELSE 1 END AS DateGap
              FROM #Test
              ) q1
              ) q2
              ORDER BY RowID;





              share|improve this answer


























                0












                0








                0







                Similar to the answer from Yogesh, who beat me to it.

                (hint: don't expect to be faster when typing an answer on your phone)



                SELECT 
                RowID, FileDate, TableName, IndexName,
                ROW_NUMBER() OVER (PARTITION BY TableName, IndexName, DateRank ORDER BY FileDate DESC) AS Rnk
                FROM
                (
                SELECT *,
                SUM(DateGap) OVER (PARTITION BY TableName, IndexName ORDER BY FileDate DESC) AS DateRank
                FROM
                (
                SELECT RowID, FileDate, TableName, IndexName,
                -- Rnk as ExpRnk,
                CASE WHEN DATEDIFF(DAY, FileDate, LAG(FileDate) OVER (PARTITION BY TableName, IndexName ORDER BY FileDate DESC)) <= 1 THEN 0 ELSE 1 END AS DateGap
                FROM #Test
                ) q1
                ) q2
                ORDER BY RowID;





                share|improve this answer













                Similar to the answer from Yogesh, who beat me to it.

                (hint: don't expect to be faster when typing an answer on your phone)



                SELECT 
                RowID, FileDate, TableName, IndexName,
                ROW_NUMBER() OVER (PARTITION BY TableName, IndexName, DateRank ORDER BY FileDate DESC) AS Rnk
                FROM
                (
                SELECT *,
                SUM(DateGap) OVER (PARTITION BY TableName, IndexName ORDER BY FileDate DESC) AS DateRank
                FROM
                (
                SELECT RowID, FileDate, TableName, IndexName,
                -- Rnk as ExpRnk,
                CASE WHEN DATEDIFF(DAY, FileDate, LAG(FileDate) OVER (PARTITION BY TableName, IndexName ORDER BY FileDate DESC)) <= 1 THEN 0 ELSE 1 END AS DateGap
                FROM #Test
                ) q1
                ) q2
                ORDER BY RowID;






                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Nov 16 '18 at 18:35









                LukStormsLukStorms

                14.2k31734




                14.2k31734






























                    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%2f53342692%2ft-sql-identifying-gaps-in-broken-sequence-of-dates%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

                    List item for chat from Array inside array React Native

                    Thiostrepton

                    Caerphilly