Re: Given a set of daterange, finding the continuous range thatincludes a particular date

Поиск
Список
Период
Сортировка
От Adrian Klaver
Тема Re: Given a set of daterange, finding the continuous range thatincludes a particular date
Дата
Msg-id 53425537-1378-bd5d-4362-4f5dec5b8d7a@aklaver.com
обсуждение исходный текст
Ответ на Re: Given a set of daterange, finding the continuous range thatincludes a particular date  (Adrian Klaver <adrian.klaver@aklaver.com>)
Список pgsql-general
On 02/22/2018 09:05 PM, Adrian Klaver wrote:
> On 02/22/2018 05:23 PM, Ken Tanzer wrote:
>>
>>
>> On Thu, Feb 22, 2018 at 5:05 PM, Adrian Klaver 
>> <adrian.klaver@aklaver.com <mailto:adrian.klaver@aklaver.com>> wrote:
>>
>>     On 02/22/2018 04:58 PM, Ken Tanzer wrote:
>>
>>
>>
>>         On Thu, Feb 22, 2018 at 4:53 PM, Adrian Klaver
>>         <adrian.klaver@aklaver.com <mailto:adrian.klaver@aklaver.com>
>>         <mailto:adrian.klaver@aklaver.com
>>         <mailto:adrian.klaver@aklaver.com>>> wrote:
>>
>>              On 02/22/2018 04:44 PM, Ken Tanzer wrote:
>>
>>                  Hi, hoping to get some help with this.  I'm needing to
>>         take a
>>                  specific date, a series of dateranges  and, given a
>>         specific
>>                  date, return a single conitinuous daterange that
>>         includes that date.
>>
>>                  To elaborate a bit, I've got lots of tables that
>>         include start
>>                  and end dates.  For example:
>>
>>                  CREATE TABLE tbl_staff_assign (
>>                        staff_assign_id         SERIAL PRIMARY KEY,
>>                        client_id               INTEGER NOT NULL 
>> REFERENCES
>>                  tbl_client (client_id),
>>                        staff_id                INTEGER REFERENCES
>>                  tbl_staff(staff_id),
>>                        staff_assign_type_code      VARCHAR(10) NOT NULL
>>                  REFERENCES tbl_l_staff_assign_type
>>         (staff_assign_type_code),
>>                        staff_assign_date           DATE NOT NULL,
>>                        staff_assign_date_end       DATE,
>>                  ...
>>
>>                  So a client might leave a progrma and then return
>>         later, or they
>>                  might simply switch to another staff_id.  (In which
>>         case one
>>                  record will have and end date, and the next record will
>>         start on
>>                  the next day.)  In this case I need to know "what
>>         period were
>>                  they continuously in the program that includes X date?"
>>           So I'd
>>                  like to be able to do something like:
>>
>>                  "SELECT staff_assign_date,continuous_daterange(
>>                  staff_assign_date, (SELECT
>>         array_agg(daterange(staff_assign_date,staff_assign_date_end,'[]')
>>                  ) FROM staff_assign sa2 WHERE
>>         sa2.client_id=sa.client_id) FROM
>>                  staff_assign sa
>>
>>                  I've done this before with procedures specific to a
>>         particular
>>                  table, and working with the start and end dates.  I'm 
>> now
>>                  wanting to try to do this once generically that will
>>         work for
>>                  all my cases.  So I'm hoping to do this in a way that
>>                  performance isn't horrible.  And it's a little unclear
>>         to me how
>>                  much and how I might be able to use the daterange
>>         operators to
>>                  accomplish this efficiently.
>>
>>
>>              The operator I use to solve similar problems:
>>
>>         https://www.postgresql.org/docs/10/static/functions-range.html
>>         <https://www.postgresql.org/docs/10/static/functions-range.html>
>>         <https://www.postgresql.org/docs/10/static/functions-range.html
>>         <https://www.postgresql.org/docs/10/static/functions-range.html>>
>>
>>              @>      contains element         
>> '[2011-01-01,2011-03-01)'::tsrange
>>              @> '2011-01-10'::timestamp   t
>>
>>
>>         Thanks Adrian.  But how would you apply that to this situation,
>>         where I have a series of (quite possibly discontinuous) 
>> dateranges?
>>
>>
>>     This is going to depend on a more formal definition of the problem
>>     with some sample data. Right now I am trying to reconcile "what
>>     period were they continuously in the program that includes X date?"
>>     with "where I have a series of (quite possibly discontinuous)
>>     dateranges? " Maybe its just me,  I can't see how discontinuous can
>>     also be continuously.
>>
>>
>>
>> *Start   End*
>> -- Episode 1
>> 1/1/16  3/30/16
>> 4/1/16  4/30/16
>> -- Episode 2
>> 1/1/18  1/31/18
>> 2/1/18  NULL
>>
>> Given 1/15/18, should return 1/1/18-->NULL
>> Given 1/15/16, should return 1/1/16-->4/30/16
> 
> Just thinking out loud here, in a function:
> 
> 1) For a client_id you can find the min(staff_assign_date).
> 
> 2) You can create a max(staff_assign_date_end) by using 
> COALESCE(staff_assign_date_end, current_date)
> 
> 3) You now have the outer range for the episodes.
> 
> 4) In that range of dates for each staff_assign_date you find the 
> staff_assign_date_end that greater then the staff_assign_date but less 
> then the next staff_assign_date. That will give you your episodes.
> 
> 5) You can then test to see if the X date is in the calculated episodes.
> 
> 6) As a shortcut you can find min(staff_assign_date) that is less then 
> the X date and see if the staff_assign_date_end is greater then the X date.
> 

Correction to 6)

6) As a shortcut you can find max(staff_assign_date) that is less then 
the X date and see if the staff_assign_date_end is greater then the X date.


-- 
Adrian Klaver
adrian.klaver@aklaver.com


В списке pgsql-general по дате отправления:

Предыдущее
От: Adrian Klaver
Дата:
Сообщение: Re: Given a set of daterange, finding the continuous range thatincludes a particular date
Следующее
От: Paul Jungwirth
Дата:
Сообщение: Re: Given a set of daterange, finding the continuous range thatincludes a particular date