Question

I have two tables: items and prices (one-to-many)

Each item has a default price, but this price can be overriden in this second table (under some circumstances).

Firstly I had a problem of fetching all the items and pre-calculate the MINIMUM PRICE - MIN between default and its overriding current price (if any ?).

You can see it here: http://sqlfiddle.com/#!2/f31d5/25

Luckily, it was solved, thanks to stackoverflow (you can see it here: Rails select subquery (without finder_sql, if possible)), but now I have similar kind of a problem!

Once I have all the items selected, can I determine the absolute MIN (or MAX) price AMONG the newly calculated field (min_price) ?

Of course I've tried something like this: http://sqlfiddle.com/#!2/f31d5/26

But, it did not work. Is there any smart SQL-true way to get these values ?

For this particular scenario in SQLFiddle it should return 5 (MIN), or 500 (MAX)

Of course I could have selected it straight-away from pricing table like this:

SELECT MIN(price) FROM prices;

But, I cannot rely on it, since item's default price might be lower and this way I cannot check it (I think, SELECT MIN/MAX does not work with JOIN or GROUP BY).

And also one thing to be aware of - I'm writing this for my search system and this is just a small part of it, so, "WHERE"-clause is pretty important there as well, because NOT all items are actually involved.

Is there any SMART way (SQL-way) I can solve this problem?

P.S Temporarily I've solved the problem simply by making a query that orders by min_price (ASC/DESC) and applying LIMIT 1 and then gathering the needed value from the item record itself, but I'm very unhappy with this solution, so I've decided to ask about it here.

Thanks

P.P.S Totally forgot to mention, that there is no way I can avoid this SQL-query, because I have a pagination system that actually appends LIMIT X, OFFSET Y. So, I need to select the value GLOBALLY, not just for a particular page!

Was it helpful?

Solution

You don't need the second call to min(). I think this does what you want:

SELECT LEAST(IFNULL(MIN(prices.price),
                    items.default_price),
             default_price) as min_price
FROM items LEFT OUTER JOIN
      prices
      ON prices.item_id = items.id
GROUP BY items.id;

If you want the lowest price across all items, you can remove the group by clause. However, I think a subquery is clearer about the intention:

select min(min_price)
from (SELECT LEAST(IFNULL(MIN(prices.price),
                          items.default_price),
                   default_price) as min_price
      FROM items LEFT OUTER JOIN
            prices
            ON prices.item_id = items.id
      GROUP BY items.id
     ) p;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top