0

Suppose I have a table like this:

id | price | group1
1  | 6     | some_group
2  | 7     | some_group
3  | 8     | some_group
4  | 9     | some_other_group

If I want to select the lowest price grouped by group1

I can just do this:

SELECT id, min(price), group1 FROM some_table GROUP BY group1;

The problem is when I have a table which is not sorted by price like this:

id | price | group1
1  | 8     | some_group
2  | 7     | some_group
3  | 6     | some_group
4  | 9     | some_other_group

Then my query returns this result set:

id | price | group1
1  | 6     | some_group
4  | 9     | some_other_group

The problem is that I get 1 in the id column but the id of the row with the price of 6 is not 1 but 3. My question is that how can I get the values from the row which contains the minimum price when I use GROUP BY?

I tried this:

SELECT f.id, min(f.price), f.group1 FROM (SELECT * FROM some_table ORDER BY price) f
GROUP BY f.group1;

but this is really slow and if I have multiple columns and aggregations it may fail.

Please note that the names above are just for demonstration purposes. My real query looks like this:

SELECT depdate, retdate, min(totalprice_eur) price FROM
    (SELECT * FROM flight_results
     WHERE (
     fromcity = 30001350
     AND tocity = 30001249
     AND website = 80102118
     AND roundtrip = 1
     AND serviceclass = 1 
     AND depdate > date(now()))
     ORDER BY totalprice_eur) F
WHERE (
fromcity = 30001350
AND tocity = 30001249
AND website = 80102118
AND roundtrip = 1
AND serviceclass = 1
AND depdate > date(now()))
GROUP BY depdate,retdate

and there is a concatenated primary key including website, fromcity, tocity, roundtrip, depdate, and retdate. There are no other indexes.

Explain says:

id  select_type table   type    possible_keys   key key_len ref rows    Extra
1   PRIMARY <derived2>  ALL NULL    NULL    NULL    NULL    2837    Using where; Using temporary; Using filesort
2   DERIVED flight_results  ALL PRIMARY NULL    NULL    NULL    998378  Using filesort
4

1 回答 1

2

你可以这样做:

SELECT t1.id, t1.price, t1.group1
FROM some_table AS t1
INNER JOIN
(
  SELECT min(price) minprice, group1 
  FROM some_table 
  GROUP BY group1
) AS t2 ON t1.price = t2.minprice AND t1.group1 = t2.group1;
于 2013-07-18T09:42:02.470 回答