我有点麻烦这个问题。
我有两张表items
和stocks
items
id | name
1 | item_1
2 | item_2
stocks
id | item_id | quantity | expired_on
1 | 1 | 5 | 2015-11-12
2 | 1 | 5 | 2015-11-13
3 | 2 | 5 | 2015-11-12
4 | 2 | 5 | 2015-11-14
我希望能够检索按日期分组的大表,并且对于每个日期,按item_id分组,并显示未过期的数量总和。
result
date | item_id | unexpired
2015-11-11 | 1 | 10
2015-11-11 | 2 | 10
2015-11-12 | 1 | 5
2015-11-12 | 2 | 5
2015-11-13 | 1 | 0
2015-11-13 | 2 | 5
2015-11-14 | 1 | 0
2015-11-14 | 2 | 0
如果只有一天,我就能检索到结果
SELECT
items.id, SUM(stocks.quantity) as unexpired
FROM
items LEFT OUTER JOIN stocks
ON items.id = stocks.item_id
WHERE
stocks.expired_on > '2015-11-11'
GROUP BY
items.id, stocks.quantity
我四处搜索,找到了一个名为DatePart的东西,但它看起来不像我需要的东西。
答案 0 :(得分:5)
使用从boolean
到integer
的方便演员,产生0,1或null,仅对未到期的
select
to_char(d, 'YYYY-MM-DD') as date,
item_id,
sum(quantity * (expired_on > d)::int) as unexpired
from
stocks
cross join
generate_series(
'2015-11-11'::date, '2015-11-14', '1 day'
) d(d)
group by 1, 2
order by 1, 2
;
date | item_id | unexpired
------------+---------+-----------
2015-11-11 | 1 | 10
2015-11-11 | 2 | 10
2015-11-12 | 1 | 5
2015-11-12 | 2 | 5
2015-11-13 | 1 | 0
2015-11-13 | 2 | 5
2015-11-14 | 1 | 0
2015-11-14 | 2 | 0
cross join
generate_series
提供给定范围内的所有日期。
上面使用的数据:
create table stocks (
id int,
item_id int,
quantity int,
expired_on date
);
insert into stocks (id,item_id,quantity,expired_on) values
(1,1,5,'2015-11-12'),
(2,1,5,'2015-11-13'),
(3,2,5,'2015-11-12'),
(4,2,5,'2015-11-14');
答案 1 :(得分:1)
您需要生成日期列表,然后使用交叉联接来获取日期和项目的完整组合。然后,库存表的left join
表示每个日期到期。累计和 - 反向计算unexpired
:
select d.dte, i.item_id,
sum(quantity) over (partition by i.item_id
order by d.dte desc
rows between unbounded preceding and 1 preceding
) as unexpired
from (select generate_series(min(expired_on) - interval '1 day', max(expired_on), interval '1 day') as dte
from stocks
) d cross join
items i left join
stocks s
on d.dte = s.expired_on and i.item_id = s.item_id;