Reputation: 33186
I am making a website to compare product prices between different stores. I have created a search function where I want to display the current lowest price and this is where I am a bit stuck.
I have a table Products
with the basic information and a table product_store
with the prizes in different stores for different products. Below is a basic schema of the database for these tables:
+-----------+ +---------------+
| products | | product_store |
+-----------+ +---------------+
| id | | product_id |
| name | | store_id |
+-----------+ | price |
| created_at |
+---------------+
The product_store
table has multiple prices for the same product_id
and store_id
so I can create a price history.
Now I would like to create a query to get all products and their lowest price at the moment. So, you take the price for each store with the highest created_at
, and from this collection I want to get the lowest value.
This is what I have tried so far:
select products.*, prices.price
from products
left join (
SELECT p1.product_id, min(p1.price) as price, p1.created_at
FROM product_store p1
WHERE p1.created_at = (SELECT max(created_at) FROM product_store p2 WHERE p2.store_id = p1.store_id
) as prices
on prices.product_id = products.id
I search for the highest created_at
per store and product and get the lowest price for these rows. However this gives some very strange results where the prices get mixed up between the products and some products that have prices don't have any in the results.
Can someone help me to create a good query for this problem?
Thanks in advance. :)
Upvotes: 1
Views: 4722
Reputation: 1269563
Here is one method. It aggregates the product_store
table to get the maximum created date for each store. Then it joins it back to that table to get price
and finally does an aggregation in the outer query:
select p.*, min(ps.price)
from products p left join
(select ps.product_id, ps.store_id, max(created_at) as maxca
from product_store ps
group by ps.product_id, ps.store_id
) pssum
on pssum.product_id = p.id left join
product_store ps
on ps.product_id = pssum.product_id and
ps.store_id = pssum.store_id and
ps.created_at = pssum.maxca
group by p.id;
Your product_store
table is an example of a slowly changing dimension. If it were set up with a eff_date
and end_date
(effective date and end date) columns, then the query would be easier to write and probably more efficient in terms of performance.
Upvotes: 2