Reputation: 86657
Table airports
:
id | from | to | price | photo | notes
_______________________________________
1 | LON | JFK| 1000 | | test
2 | LON | JFK| 2000 | | test2
I want to retrieve the bestprice entry of all from-to
combinations inside the database.
I want to fetch the whole record that is minprice found, or at least specific tables.
The following works, BUT only gives me the 3 columns from, to, price. Not the whole entity.
SELECT from, to, min(price) FROM airports GROUP BY from, to
How would I have to adapt this?
Upvotes: 0
Views: 125
Reputation:
This is typically done using window functions:
select id, "from", "to", price, photo, notes
from (
select id, "from", "to", price, photo, notes
min(price) over (partition by "from", "to") as min_price
from the_table
) t
where price = min_price
order by id;
from
is a reserved word and it's a bad idea to use that as a column name (not entirely sure about to
)
To deal with "ties" (same values in from, to and price), you can use the dense_rank()
function instead:
select id, "from", "to", price, photo, notes
from (
select id, "from", "to", price, photo, notes
dense_rank() over (partition by "from", "to" order by price) as price_rank
from the_table
) t
where price_rank = 1
order by id;
Upvotes: 4
Reputation: 3576
If you want to get the entire data, here is a query that solve your problem:
SELECT A.*
FROM airports A
INNER JOIN (SELECT A2.fromhere
,A2.tohere
,MIN(A2.price) AS minprice
FROM airports A2
GROUP BY A2.fromhere, A2.tohere) T ON T.fromhere = A.fromhere
AND T.tohere = A.tohere
AND T.minprice = A.price
The jointure is used to get only the best prices for each couple fromhere/tohere.
Hope this will help you.
Upvotes: 0
Reputation: 2091
A very simple solution would be this. SQLFiddle here
SELECT *
FROM airports
WHERE (from_place, to_place, price) =
(SELECT from_place, to_place, min(price)
FROM airports
GROUP BY from_place, to_place);
Use SELECT * FROM ...
since you want the whole entity.
Upvotes: 1
Reputation: 131
There isn't going to be a way to get a "whole entity" there could be many rows in your table that could contain the matching from + to + min price
For example if your table contains
id | from | to | price | photo | notes
_______________________________________
1 | LON | JFK| 1000 | | test
2 | LON | JFK| 2000 | | test2
3 | LON | JFK| 5000 | | test3
4 | LON | JFK| 2000 | | test4
5 | LON | JFK| 1000 | | test5
Then both rows 1 and 5 meet your criteria of from + to + min price.
You could write the query
SELECT id, from, to, price, photo, notes
FROM airports a
INNER JOIN (
SELECT from, to, min(price) [price]
FROM airports
GROUP BY from, to) sub
ON sub.from = a.from
AND sub.to = a.to
AND sub.price = a.price
Which would get you the matching records.
Upvotes: 0
Reputation: 690
You can order the results and use distinct on to take the first result from each grouping
select distinct on (from,to) * from airports order by from,to,price asc;
the above query should work
Upvotes: 1