I'd like to show the observation number for each record returned by a PostgreSQL query.
I think in 8.4 windowing functions can perform this capability.
I'd like to show the observation number for each record returned by a PostgreSQL query.
I think in 8.4 windowing functions can perform this capability.
select row_number() over (order by <field> nulls last) as rownum, *
from foo_tbl
order by <field>
If order is not necessary, this answer may also be simplified:
select row_number() over(), * -- notice: no fields are needed
from foo_tbl
SQL Fiddle Proof of Concept
over()
then it always gives rownumbers incrementally, like 1 2 3 4...
in order of that particular result (if there are outer queries that rearrange results, then rownum could become out of order ref: https://mcmap.net/q/169475/-sql-server-2005-row_number-without-order-by, so adding an order by
might be useful in those cases (or if you want to not count nulls, as in the first example). FWIW. –
Spinous over()
does above. If you haven't supplied it any conditions, there'd be one pane for the entire window. Window functions
are unique in that they can do calculations across the rows of a frame, instead of a whole result set. So if you wanted to do row_number
by sex, you can use your over to partition by sex. –
Balzac For versions prior to 8.4:
SELECT count(*) rownum, foo.*
FROM datatable foo
JOIN datatable bar
ON (foo.pk_id <= bar.pk_id)
GROUP BY foo.pk_id, foo.a, foo.b
ORDER BY rownum
;
-- if there isn't a single unique/primary key field, you can concatenate fields
-- Example: ON (foo.a||foo.b||foo.c <= bar.a||bar.b||bar.c)
Hope this helps someone.
SQL Fiddle Proof of Concept
I suggest avoiding this at all cost, but wanted to include it for posterity. It is somewhat expensive and I imagine does not scale well, but when a primary key does not exist on a table (bad db-design), your options may be limited. In most of those cases the recommendation is to perform numbering at the application layer.
-- Based on basic table w/o primary key
-- CREATE TABLE names ( name as text );
SELECT num, name[num]
FROM (
select generate_series( 1, (select count(*) from names) ) as num
) _nums,
(
select array_agg(name) as name from names
) _names
SQL Fiddle Proof of Concept
Reasons it doesn't scale:
null
values should concatentate to null
. Thus, a coalesce()
may need to be used. –
Balzac © 2022 - 2024 — McMap. All rights reserved.