Getting results between two dates in PostgreSQL

前端 未结 8 1587
感动是毒
感动是毒 2020-12-07 22:59

I have the following table:

+-----------+-----------+------------+----------+
| id        | user_id   | start_date | end_date |
| (integer) | (integer) | (da         


        
相关标签:
8条回答
  • 2020-12-07 23:10

    just had the same question, and answered this way, if this could help.

    select * 
    from table
    where start_date between '2012-01-01' and '2012-04-13'
    or    end_date   between '2012-01-01' and '2012-04-13'
    
    0 讨论(0)
  • 2020-12-07 23:12
    SELECT *
    FROM ecs_table
    WHERE (start_date, end_date) OVERLAPS ('2012-01-01'::DATE, '2012-04-12'::DATE + interval '1');
    
    0 讨论(0)
  • 2020-12-07 23:15

    You have to use the date part fetching method:

    SELECT * FROM testbed WHERE start_date  ::date >= to_date('2012-09-08' ,'YYYY-MM-DD') and date::date <= to_date('2012-10-09' ,'YYYY-MM-DD')
    
    0 讨论(0)
  • 2020-12-07 23:17

    Looking at the dates for which it doesn't work -- those where the day is less than or equal to 12 -- I'm wondering whether it's parsing the dates as being in YYYY-DD-MM format?

    0 讨论(0)
  • 2020-12-07 23:21

    No offense but to check for performance of sql I executed some of the above mentioned solutiona pgsql.

    Let me share you Statistics of top 3 solution approaches that I come across.

    1) Took : 1.58 MS Avg

    2) Took : 2.87 MS Avg

    3) Took : 3.95 MS Avg

    Now try this :

     SELECT * FROM table WHERE DATE_TRUNC('day', date ) >= Start Date AND DATE_TRUNC('day', date ) <= End Date
    

    Now this solution took : 1.61 Avg.

    And best solution is 1st that suggested by marco-mariani

    0 讨论(0)
  • 2020-12-07 23:22

    Assuming you want all "overlapping" time periods, i.e. all that have at least one day in common.

    Try to envision time periods on a straight time line and move them around before your eyes and you will see the necessary conditions.

    SELECT *
    FROM   tbl
    WHERE  start_date <= '2012-04-12'::date
    AND    end_date   >= '2012-01-01'::date;
    

    This is sometimes faster for me than OVERLAPS - which is the other good way to do it (as @Marco already provided).

    Note the subtle difference (per documentation):

    OVERLAPS automatically takes the earlier value of the pair as the start. Each time period is considered to represent the half-open interval start <= time < end, unless start and end are equal in which case it represents that single time instant. This means for instance that two time periods with only an endpoint in common do not overlap.

    Bold emphasis mine.

    Performance

    For big tables the right index can help performance (a lot).

    CREATE INDEX tbl_date_inverse_idx ON tbl(start_date, end_date DESC);
    

    Possibly with another (leading) index column if you have additional selective conditions.

    Note the inverse order of the two columns. Detailed explanation:

    • Optimizing queries on a range of timestamps (two columns)
    0 讨论(0)
提交回复
热议问题