Project a time range in multiple rows with Postgres I have some rows like this:

 avg_income | date_from  | date_to
------------+------------+------------
     1256.9 | 2016-11-21 | 2017-07-10
     4383.2 | 2017-05-06 | 2017-06-01


and I would like to project the avg_income values to the respective months, like this:

 avg_income | month
------------+------------
     1256.9 | 2016-11-01 
     1256.9 | 2016-12-01 
     1256.9 | 2017-01-01 
     1256.9 | 2017-02-01 
     1256.9 | 2017-03-01 
     1256.9 | 2017-04-01 
     1256.9 | 2017-05-01 
     1256.9 | 2017-06-01 
     1256.9 | 2017-07-01 
     4383.2 | 2017-05-01 
     4383.2 | 2017-06-01 


So far I just came out with an awful FOR/LOOP/generate_series(...) so I am wondering is there a more elegant (and efficient) way to do it?
You can use generate_series() for this. 

select t.avg_income, d.month
from the_table t
  cross join lateral ( 
    select g.m::date as month
    from generate_series(date_trunc('month', t.date_from), date_trunc('month', t.date_to), interval '1 month') as g (m)
  ) as d
order by t.avg_income, d.month;


Alternatively:

select t.avg_income, d.month::date
from the_table t
  cross join lateral generate_series(date_trunc('month', t.date_from), date_trunc('month', t.date_to), interval '1 month') as d (month)
order by t.avg_income, d.month;


Online example: http://rextester.com/ADG4243