mysql - SQL select only rows with max value on a column -
i have table documents (simplified version here):
+------+-------+--------------------------------------+ | id | rev | content | +------+-------+--------------------------------------+ | 1 | 1 | ... | | 2 | 1 | ... | | 1 | 2 | ... | | 1 | 3 | ... | +------+-------+--------------------------------------+ how select 1 row per id , greatest rev?
above data, result should contain 2 rows: [1, 3, ...] , [2, 1, ..]. i'm using mysql.
currently use checks in while loop detect , over-write old revs resultset. method achieve result? isn't there sql solution?
update
answers suggest, there is sql solution, , here sqlfiddle demo.
update 2
noticed after adding above sqlfiddle, rate @ question upvoted has surpassed upvote rate of answers. has not been intention! fiddle is based on answers, accepted answer.
at first glance...
all need group by clause max aggregate function:
select id, max(rev) yourtable group id it's never simple, it?
i noticed need content column well.
this common question in sql: find whole data row max value in column per group identifier. heard lot during career. actually, 1 questions answered in current job's technical interview.
it is, actually, common stackoverflow community has created single tag deal questions that: greatest-n-per-group.
basically, have 2 approaches solve problem:
joining simple group-identifier, max-value-in-group sub-query
in approach, first find group-identifier, max-value-in-group (already solved above) in sub-query. join table sub-query equality on both group-identifier , max-value-in-group:
select a.id, a.rev, a.contents yourtable inner join ( select id, max(rev) rev yourtable group id ) b on a.id = b.id , a.rev = b.rev left joining self, tweaking join conditions , filters
in approach, left join table itself. equality, of course, goes in group-identifier. then, 2 smart moves:
- the second join condition having left side value less right value
- when step 1, row(s) have max value have
nullin right side (it'sleft join, remember?). then, filter joined result, showing rows right sidenull.
so end with:
select a.* yourtable left outer join yourtable b on a.id = b.id , a.rev < b.rev b.id null; conclusion
both approaches bring exact same result.
if have 2 rows max-value-in-group group-identifier, both rows in result in both approaches.
both approaches sql ansi compatible, thus, work favorite rdbms, regardless of "flavor".
both approaches performance friendly, mileage may vary (rdbms, db structure, indexes, etc.). when pick 1 approach on other, benchmark. , make sure pick 1 make of sense you.
Comments
Post a Comment