0

Data set example is as follows:

noteid seq notebalance
1       4      125.00
1       3      120.00
2       8      235.00
2       6      235.00
2       5      200.00
3       9      145.00
4       17     550.00
4       16     550.00
4       14     500.00
4       12     450.00
4       10     400.00
...

so we basically have the latest notebalance at the beginning of each noteid group.

What is the proper sql syntax to obtain the latest balances for each noteid?

as in:

1       4      125.00
2       8      235.00
3       9      145.00
4       17     550.00

3 Answers3

3

A generic (= ANSI SQL) solution would be to use a window function:

select noteid, seq, notebalance
from (
   select noteid, seq, notebalance,
          row_number() over (partition by noteid order by seq desc) as rn
   from the_table
) t
where rn = 1
order by noteid;

When using Postgres, it's usually faster to use the distinct on operator:

select distinct on (noteid) noteid, seq, notebalance
from the_table
order by noteid, seq desc;

SQLFiddle example: http://sqlfiddle.com/#!15/8ca27/2

  • The Postgres-only version is also, in my experience, optimized and fast. The window version, not, at least not always. – Andrew Lazarus Apr 19 '14 at 04:58
  • @AndrewLazarus: "fast" is relative. If the alternative is a join between the table and a query that does a `group by` the then window function will be faster. –  Apr 19 '14 at 07:01
0

I think ROW_NUMBER() is what you are looking for. This is similar to this SO question.

Community
  • 1
  • 1
Bazinga
  • 994
  • 4
  • 14
  • 42
0

"the record with the highest seq" := "there is no record with a higher seq (for this noteid)"

SELECT noteid, seq, notebalance
FROM the_table tt
WHERE NOT EXISTS (
  SELECT * FROM the_table nx
  WHERE nx.noteid = tt.noteid
  AND nc.seq > tt.seq
  )
ORDER BY noteid
 ;
wildplasser
  • 43,142
  • 8
  • 66
  • 109