I have two tables:
orders
| id | item_id | quantity | ordered_on |
|----|---------|----------|------------|
| 1 | 1 | 2 | 2016-03-09 |
| 2 | 1 | 2 | 2016-03-12 |
| 3 | 4 | 3 | 2016-03-15 |
| 4 | 4 | 3 | 2016-03-13 |
stocks
| id | item_id | quantity | enter_on | expire_on |
|----|---------|----------|------------|------------|
| 1 | 1 | 10 | 2016-03-07 | 2016-03-10 |
| 2 | 1 | 20 | 2016-03-11 | 2016-03-15 |
| 3 | 1 | 20 | 2016-03-14 | 2016-03-17 |
| 4 | 4 | 10 | 2016-03-14 | NULL |
| 5 | 4 | 10 | 2016-03-12 | NULL |
I'm trying to create a view to show the orders along with their closest stocks enter_on
like this (I'm using include_after
and include_before
to give an overview on which date I want to exclude the item that's preordered, so the stock would reflect correctly.)
include_after
is always going to be the stock that came in but not expired yet, if expired, show NULL, include_before
will always show the next incoming stock enter_on
, unless there's an expire_on
that's earlier than the next enter_on
.
| item_id | quantity | ordered_on | include_after | include_before |
|---------|----------|------------|---------------|----------------|
| 1 | 2 | 2016-03-09 | 2016-03-07 | 2016-03-10 |
| 1 | 2 | 2016-03-12 | 2016-03-11 | 2016-03-14 |
| 4 | 3 | 2016-03-13 | 2016-03-12 | 2016-03-14 |
| 4 | 3 | 2016-03-15 | 2016-03-14 | NULL |
So this is what I came up with:
SELECT
o.item_id, o.quantity, o.order_on, (
SELECT COALESCE(MAX(s.enter_on), NULL::DATE)
FROM stocks s
WHERE s.enter_on <= o.order_on AND s.item_id = o.item_id
) as include_after, (
SELECT COALESCE(MIN(s.enter_on), NULL::DATE)
FROM stocks s
WHERE s.enter_on > o.order_on AND s.item_id = o.item_id
) as include_before
FROM
orders o;
It works fine (I haven't included the expire_on
part), but I'm worrying about performance issue for using two subqueries in the select.
Does anyone have some alternative suggestions?
UPDATE
I'm using Postgresql 9.4 (Can't add anymore tags)
the actual problem is way more complicated than I stated, it's a lot of tables joined together and views, I shrunk it down to just one table to grasp the concept if there are alternatives