I have this working request, but I need to add all the months to my result, regardless of whether the products were sold during this month:
select * from ( select to_char(max(change_date), 'YYYY-MON')::varchar(8) as yyyymmm, max(change_date) as yearmonth, sum(vic.sold_qty / item_size.qty)::numeric(18,2) as sold_qty, -- sold monthly sum(sum(on_hand)) OVER (PARTITION BY vic.item_id order by year,month) as on_hand --running balance from (((view_item_change vic left join item on vic.item_id = item.item_id) left join item_size on item_size.item_id = vic.item_id and item_size.name = item.sell_size) left join item_plu on vic.item_id = item_plu.item_id and item_plu.seq_num = 0) where 1 = 1 -- cannot limit date here as its used to show running balance. and vic.change_date < current_date - date_part('day',current_date)::integer --show only till end of last month and item.item_id = (select item_id from item_plu where number = '51515') group by vic.item_id, year, month ) as t where yearmonth > current_date - date_part('day',current_date)::integer - 540 -- 18 months
which gives me something like this:
"2013-JUN";"2013-06-29";0.00;7.0000 "2013-JUL";"2013-07-22";0.00;6.0000 "2013-AUG";"2013-08-28";2.00;4.0000 "2013-SEP";"2013-09-02";0.00;4.0000 "2013-OCT";"2013-10-28";0.00;4.0000 "2013-NOV";"2013-11-15";0.00;4.0000 "2013-DEC";"2013-12-16";0.00;6.0000 "2014-FEB";"2014-02-10";1.00;5.0000 "2014-APR";"2014-04-09";0.00;5.0000
But I also want to show the months 2014-JAN and 2014-MAR so that my schedule is better scaled.
I know how to span generate_series(start_date, end_date, '1 month') , but I cannot figure out how I can join this series in the result set above.
I accepted the first answer, but after two weeks of testing I found a problem. Left-joining a series and then adding coalescence to display 0 rather than zero for empty months causes a problem with the current balance.
Result Query:
SELECT yyyymmm, yyyymmm, coalesce(sold_qty,0) sold_qty, coalesce(on_hand,0) on_hand FROM ( SELECT date_trunc('month', month_series)::date as yyyymmm FROM generate_series(current_date - date_part('day',current_date)::integer - 540 ,current_date- date_part('day',current_date)::integer , interval '1 month') month_series ) month_series LEFT JOIN ( select * from ( select date_trunc('month', max(change_date))::date as yyyymmm, max(change_date) as yearmonth, sum(vic.sold_qty / item_size.qty)::numeric(18,2) as sold_qty, sum(sum(on_hand)) OVER (PARTITION BY vic.item_id order by year,month) as on_hand from (((view_item_change vic left join item on vic.item_id = item.item_id) left join item_size on item_size.item_id = vic.item_id and item_size.name = item.sell_size) left join item_plu on vic.item_id = item_plu.item_id and item_plu.seq_num = 0) where 1 = 1
The results that I get:
"2013-07-01";"2013-07-01";0;0 "2013-08-01";"2013-08-01";0;0 "2013-09-01";"2013-09-01";1.00;53.0000 "2013-10-01";"2013-10-01";0;0 "2013-11-01";"2013-11-01";0;0 "2013-12-01";"2013-12-01";0.00;53.0000 "2014-01-01";"2014-01-01";0.00;52.0000 "2014-02-01";"2014-02-01";0;0 "2014-03-01";"2014-03-01";0;0 "2014-04-01";"2014-04-01";0;0
But I want:
"2013-07-01";"2013-07-01";0;53.0000 "2013-08-01";"2013-08-01";0;53.0000 "2013-09-01";"2013-09-01";1.00;53.0000 "2013-10-01";"2013-10-01";0;53.0000 "2013-11-01";"2013-11-01";0;0;53.0000 "2013-12-01";"2013-12-01";0.00;53.0000 "2014-01-01";"2014-01-01";0.00;52.0000 "2014-02-01";"2014-02-01";0;0;52.0000 "2014-03-01";"2014-03-01";0;0;52.0000 "2014-04-01";"2014-04-01";0;0;52.0000
Table definitions
CREATE TABLE item ( item_id character(22) NOT NULL, version integer NOT NULL, created_by character varying(16) NOT NULL, updated_by character varying(16), inactive_by character varying(16), created_on date NOT NULL, updated_on date, inactive_on date, external_id numeric(14,0), description character varying(40) NOT NULL, dept_id character(22), subdept_id character(22), sell_size character varying(8) NOT NULL, purch_size character varying(8) NOT NULL ); CREATE TABLE item_change ( item_id character(22) NOT NULL, size_name character varying(8) NOT NULL, store_id character(22) NOT NULL, change_date date NOT NULL, on_hand numeric(18,4) NOT NULL,
There is only one row per month, because I also do a group by year, month. As you can see, the view has the columns year, quarter, month, week, dow for ease of reporting.
To get working data for this, if necessary, I can do it, but for this I will need it manually. I simplified the tables and left all the restrictions and some columns.