MySQL groupwise max by the length of a field
-
11-12-2019 - |
Question
Product
table:
id: int
name: varchar(255)
info: varchar(8000)
I need to get a list of all products, grouped by name, and if some products have the same name then the one with the most data in info
field should be picked to show. Another requirement is consistency - the same products should be guaranteed to be displayed every time. But performance isn't my concern at all with this.
So the best I have come up with so far is this:
select * from (select * from product order by length(info) desc) as product group by name
My understanding that this should work in MySQL but does not guarantee the results.
Is there any better way?
UPDATE:
An example of what I am looking for. If the data is
1, 'Product1', '12345'
2, 'Product1', '123'
3, 'Product2', '123456'
4, 'Product2', '123456'
5, 'Product2', '12'
The expected results should be either:
1, 'Product1', '12345'
3, 'Product2', '123456'
or
1, 'Product1', '12345'
4, 'Product2', '123456'
I don't care which one of the two as long as it's the same result every time I run the query.
Solution
I think you need to do a join:
select p.*
from product p join
(select p.name, max(len(info)) as maxinfolen
from product p
group by p.name
) t
on p.name = t.name and
len(p.info) = t.maxinfolen
This will return duplicates, if the maximum length is repeated in info. To eliminate duplicates, you can group by on the outside:
select p.name, max(info)
from product p join
(select p.name, max(len(info)) as maxinfolen
from product p
group by p.name
) t
on p.name = t.name and
len(p.info) = t.maxinfolen
group by p.name
If you are trying to choose the same id every time, you can use the same idea:
select p.*
from product p join
(select p.name, min(id) as minid
from product p join
(select p.name, max(len(info)) as maxinfolen
from product p
group by p.name
) t
on p.name = t.name and
len(p.info) = t.maxinfolen
group by p.name
) t
on p.name = t.name and
p.id = t.minid