简体   繁体   中英

How to find the row with maximum attribute value with group by?

I have tables with postmen, newspapers, districts where they spread newspapers and the table 'realization' that contains data, newspaper and disctrict, postman id ,where postman spread newspaper. I have to find the most expensive newspaper in every district; I write

  SELECT * 
  FROM realization r 
  JOIN newspaper n 
  ON r.np_index = n.np_index 
  JOIN district d 
  ON d.d_id = r.d_id
  GROUP BY d.d_id
  Having n.price = Max(n.price)

And it works incorrect.

You don't get this with group by . You need to explicitly use logic to find the most expensive one in each district (there are other methods in other databases, but MySQL doesn't support them). The best to learn is probably the not exists method:

SELECT *
FROM realization r JOIN
     newspaper n 
     ON r.np_index = n.np_index JOIN
     district d 
     ON d.d_id = r.d_id
WHERE NOT EXISTS (select 1
                  from newspaper n2
                  where n2.d_id = n.d_id and
                        n2.price > n.price
                 );

The logic is saying: "Get me all rows in the original tables, where there is no newspaper with a higher price in the district". This is getting the maximum price. Note that this will return multiple rows per district, if multiple papers have the same price. To get an arbitrary one, you could add group by d.d_id to the query.

An index on newspaper(d_id, price) would help this query perform better.

Because you're using mysql, you can use its non-standard grouping to get it simply:

SELECT * FROM (
    SELECT *
    FROM realization r 
    JOIN newspaper n ON r.np_index = n.np_index 
    JOIN district d ON d.d_id = r.d_id
    ORDER BY n.price desc) x
GROUP BY d.d_id

Without funky grouping support, use a correlated subquery (which would work in all databases):

SELECT *
FROM realization r 
JOIN newspaper n ON r.np_index = n.np_index 
JOIN district d ON d.d_id = r.d_id
WHERE n.price = (
    SELECT MAX(price)
    FROM realization r2
    JOIN newspaper n2 ON r2.np_index = n2.np_index 
    JOIN district d2 ON d2.d_id = r2.d_id
    WHERE d2.d_id = d.id)

However, this second query will return all matches where there are multiple newspapers that share the same maximum price for the district.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM