Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7895657
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 3, 20262026-06-03T07:41:46+00:00 2026-06-03T07:41:46+00:00

There is a table with visits data: uid (INT) | created_at (DATETIME) I want

  • 0

There is a table with visits data:

uid (INT) | created_at (DATETIME)

I want to find how many days in a row a user has visited our app. So for instance:

SELECT DISTINCT DATE(created_at) AS d FROM visits WHERE uid = 123

will return:

     d      
------------
 2012-04-28
 2012-04-29
 2012-04-30
 2012-05-03
 2012-05-04

There are 5 records and two intervals – 3 days (28 – 30 Apr) and 2 days (3 – 4 May).

My question is how to find the maximum number of days that a user has visited the app in a row (3 days in the example). Tried to find a suitable function in the SQL docs, but with no success. Am I missing something?


UPD:
Thank you guys for your answers! Actually, I’m working with vertica analytics database (http://vertica.com/), however this is a very rare solution and only a few people have experience with it. Although it supports SQL-99 standard.

Well, most of solutions work with slight modifications. Finally I created my own version of query:

-- returns starts of the vitit series 
SELECT t1.d as s FROM testing t1
LEFT JOIN testing t2 ON DATE(t2.d) = DATE(TIMESTAMPADD('day', -1, t1.d))
WHERE t2.d is null GROUP BY t1.d

          s          
---------------------
 2012-04-28 01:00:00
 2012-05-03 01:00:00

-- returns end of the vitit series 
SELECT t1.d as f FROM testing t1
LEFT JOIN testing t2 ON DATE(t2.d) = DATE(TIMESTAMPADD('day', 1, t1.d))
WHERE t2.d is null GROUP BY t1.d

          f          
---------------------
 2012-04-30 01:00:00
 2012-05-04 01:00:00

So now only what we need to do is to join them somehow, for instance by row index.

SELECT s, f, DATEDIFF(day, s, f) + 1 as seq FROM (
    SELECT t1.d as s, ROW_NUMBER() OVER () as o1 FROM testing t1
    LEFT JOIN testing t2 ON DATE(t2.d) = DATE(TIMESTAMPADD('day', -1, t1.d))
    WHERE t2.d is null GROUP BY t1.d
) tbl1 LEFT JOIN (
    SELECT t1.d as f, ROW_NUMBER() OVER () as o2 FROM testing t1
    LEFT JOIN testing t2 ON DATE(t2.d) = DATE(TIMESTAMPADD('day', 1, t1.d))
    WHERE t2.d is null GROUP BY t1.d
) tbl2 ON o1 = o2 

Sample output:

          s          |          f          | seq 
---------------------+---------------------+-----
 2012-04-28 01:00:00 | 2012-04-30 01:00:00 |   3
 2012-05-03 01:00:00 | 2012-05-04 01:00:00 |   2
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-03T07:41:47+00:00Added an answer on June 3, 2026 at 7:41 am

    Another approach, the shortest, do a self-join:

    with grouped_result as
    (
        select 
           sr.d,
           sum((fr.d is null)::int) over(order by sr.d) as group_number
        from tbl sr
        left join tbl fr on sr.d = fr.d + interval '1 day'
    )
    select d, group_number, count(d) over m as consecutive_days
    from grouped_result
    window m as (partition by group_number)
    

    Output:

              d          | group_number | consecutive_days 
    ---------------------+--------------+------------------
     2012-04-28 08:00:00 |            1 |                3
     2012-04-29 08:00:00 |            1 |                3
     2012-04-30 08:00:00 |            1 |                3
     2012-05-03 08:00:00 |            2 |                2
     2012-05-04 08:00:00 |            2 |                2
    (5 rows)
    

    Live test: http://www.sqlfiddle.com/#!1/93789/1

    sr = second row, fr = first row ( or perhaps previous row? ツ ). Basically we are doing a back tracking, it’s a simulated lag on database that doesn’t support LAG (Postgres supports LAG, but the solution is very long, as windowing doesn’t support nested windowing). So in this query, we uses a hybrid approach, simulate LAG via join, then use SUM windowing against it, this produces group number

    UPDATE

    Forgot to put the final query, the query above illustrate the underpinnings of group numbering, need to morph that into this:

    with grouped_result as
    (
        select 
           sr.d,
           sum((fr.d is null)::int) over(order by sr.d) as group_number
        from tbl sr
        left join tbl fr on sr.d = fr.d + interval '1 day'
    )
    select min(d) as starting_date, max(d) as end_date, count(d) as consecutive_days
    from grouped_result
    group by group_number
    -- order by consecutive_days desc limit 1
    
    
    STARTING_DATE                END_DATE                     CONSECUTIVE_DAYS
    April, 28 2012 08:00:00-0700 April, 30 2012 08:00:00-0700 3
    May, 03 2012 08:00:00-0700   May, 04 2012 08:00:00-0700   2
    

    UPDATE

    I know why my other solution that uses window function became long, it became long on my attempt to illustrate the logic of group numbering and counting over the group. If I’d cut to the chase like in my MySql approach, that windowing function could be shorter. Having said that, here’s my old windowing function approach, albeit better now:

    with headers as
    (
        select 
          d,lag(d) over m is null or d - lag(d) over m  <> interval '1 day' as header
        from tbl
        window m as (order by d)
    )      
    ,sequence_group as
    (
        select d, sum(header::int) over (order by d) as group_number
        from headers  
    )
    select min(d) as starting_date,max(d) as ending_date,count(d) as consecutive_days
    from sequence_group
    group by group_number
    -- order by consecutive_days desc limit 1
    

    Live test: http://www.sqlfiddle.com/#!1/93789/21

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have a 'SessionVisit' table which collects data about user visits. The script for
In a MySQL (5.1) database table there is data that represents: how long a
There is one table , and I want the unique values of table column
I have a very big table with a lot of rows, every row has
Above is a screen cap of my schema. The visits table has a list
I've a table of Users with a one-to-many relationship on a table of Visits
in an sql table there's an id, first name and last name field. i'd
i have a t_class table in mySql, in this table there are 3 columns,
There is a table: create table table1 ( id integer primary key, user_id varchar(36),
There is a table in a databse, let's call this table Document. This table

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.