0

Let's say i have table

CREATE TABLE branch
( 
  active_from timestamp without time zone,
  active_until timestamp without time zone,
  active_years integer[]
)
  • Both active_from and active_until column was populated by timestamp value.
  • active_years is still empty.

Then i wanna generate the value of active_years by both active_from and active_until columns.

example data

|active_from          |active_until           |active_years
|'2013-01-22 00:00:00'|'2015-01-22 00:00:00'  |{2013,2014,2015}

Any idea how to query it? Thanks

--i know we can do this easily by developing mini app to solve the problem.--

2 Answers 2

3

You can generate the number of years that have passed by using the generate_series() function and then aggregate them:

select active_from, active_until, array_agg(extract(year from active_year)) as active_years
from (
  select *
  from branch
    cross join lateral generate_series(active_from, active_until, interval '1' year) as x (active_year)
) t
group by active_from, active_until;

The above requires Postgres 9.3 or later because of the lateral query.

For earlier versions you can use:

select active_from, active_until, array_agg(yr) as active_years
from (
  select active_from, active_until, extract(year from generate_series(active_from, active_until, interval '1' year)) as yr
  from branch
) t
group by active_from, active_until;

But that relies on calling a set-returning function in the select list which is discouraged, so if you are on 9.4 you should prefer the lateral join.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you very much @a_horse_with_no_name. You are briliant..:). I missed generate_series() function. I've tried to solve it with for loop. lol. I am on 9.4 and your query works briliant.
1

I guess there are several solutions...

A solution could be using the functions EXTRACT(), generate_series() and array_agg

SELECT array_agg(years) from 
  (SELECT generate_series(_from::int,_until::int) as years FROM
     (SELECT extract(year from active_from) AS _from,
             extract(year from active_until) AS _until 
      FROM branch
  ) as foo
)foo;

1 Comment

thanks @Tommaso Di Bucchianico. How can I missed to use generate_series() function. lol

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.