Numbering rows
Is there an easy way to assign a sequential number, possibly based on an
arbitrary minimum (typically 0 or 1) to each row of an ordered result
set, or do I have to work with explicit sequences?
I need to do quite a lot of maths on successive rows, extracting numeric
and timestamp differences hence rates of change. I've typically been
doing it manually or in a spreadsheet but there has to be a better way
e.g. by a join on offset row numbers.
--
Mark Morgan Lloyd
markMLl .AT. telemetry.co .DOT. uk
[Opinions above are the author's, not those of his employers or colleagues]
May be this function can help :
http://www.postgresql.org/docs/8.3/static/functions-srf.html
Ries
On Oct 15, 2008, at 1:44 PM, Mark Morgan Lloyd wrote:
Show quoted text
Is there an easy way to assign a sequential number, possibly based
on an arbitrary minimum (typically 0 or 1) to each row of an ordered
result set, or do I have to work with explicit sequences?I need to do quite a lot of maths on successive rows, extracting
numeric and timestamp differences hence rates of change. I've
typically been doing it manually or in a spreadsheet but there has
to be a better way e.g. by a join on offset row numbers.--
Mark Morgan Lloyd
markMLl .AT. telemetry.co .DOT. uk[Opinions above are the author's, not those of his employers or
colleagues]--
Sent via pgsql-general mailing list (pgsql-general@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-general
On Wed, Oct 15, 2008 at 12:08 PM, ries van Twisk <pg@rvt.dds.nl> wrote:
May be this function can help :
http://www.postgresql.org/docs/8.3/static/functions-srf.html
Using generate series won't number the rows that way that you would
want. You basically will end up with a cross join between the
generated series and the requested set. There are three ways that I
know of to get a row number:
1) IIRC use a pl-pgsql function that returns an incremented number
2) use SQL by joining using the operator ">=" and Group by aggregate count(*)
3) 8.4 has sum new analytic functions that will do this nicely.
--
Regards,
Richard Broersma Jr.
Visit the Los Angeles PostgreSQL Users Group (LAPUG)
http://pugs.postgresql.org/lapug
On Wed, Oct 15, 2008 at 1:23 PM, Richard Broersma
<richard.broersma@gmail.com> wrote:
On Wed, Oct 15, 2008 at 12:08 PM, ries van Twisk <pg@rvt.dds.nl> wrote:
May be this function can help :
http://www.postgresql.org/docs/8.3/static/functions-srf.html
Using generate series won't number the rows that way that you would
want. You basically will end up with a cross join between the
generated series and the requested set. There are three ways that I
know of to get a row number:
Can't you put the query into a subselect with an offset 0 and join to
that to get the generate_series to work correctly?
On Wed, Oct 15, 2008 at 12:32 PM, Scott Marlowe <scott.marlowe@gmail.com> wrote:
Can't you put the query into a subselect with an offset 0 and join to
that to get the generate_series to work correctly?
I've never heard of doing it that way, but I'm very interestes in
seeing how it is done. This is what i've tried so far, but am still
getting the cross join:
postgres=#
select * from generate_series(1,3)
CROSS JOIN ( values('a'),('b'),('c') ) as myvals( letter )
OFFSET 0;
generate_series | letter
-----------------+--------
1 | a
2 | a
3 | a
1 | b
2 | b
3 | b
1 | c
2 | c
3 | c
(9 rows)
--
Regards,
Richard Broersma Jr.
Visit the Los Angeles PostgreSQL Users Group (LAPUG)
http://pugs.postgresql.org/lapug
Thanks everybody- I'm watching with a lot of interest. I was worried
that I was asking something stupid with an obvious answer...
ries van Twisk wrote:
May be this function can help :
http://www.postgresql.org/docs/8.3/static/functions-srf.html
Thanks, that's already turning out to be useful for something else I was
working on today:
select percent,
to_char(nedcar_tonnes_001(percent), '99990.99') AS nedcar
from generate_series(0,110,10) as percent;
The one thing I'd say about generate_series() is that the description
suggests that one has to put an explicit count() as the second parameter
if using it to number rows, i.e. it doesn't have an "as many as
necessary" option.
--
Mark Morgan Lloyd
markMLl .AT. telemetry.co .DOT. uk
[Opinions above are the author's, not those of his employers or colleagues]
Import Notes
Reply to msg id not found: 16170243-B840-4478-BA05-99221EA67915@duplicate.rvt.dds.nl
Mark Morgan Lloyd wrote:
Is there an easy way to assign a sequential number, possibly based on an
arbitrary minimum (typically 0 or 1) to each row of an ordered result
set, or do I have to work with explicit sequences?I need to do quite a lot of maths on successive rows, extracting numeric
and timestamp differences hence rates of change. I've typically been
doing it manually or in a spreadsheet but there has to be a better way
e.g. by a join on offset row numbers.
PERL can remember variables in your session. Here's a function I wrote
that sets a "global" variable in PL/PERL:
----------
CREATE OR REPLACE FUNCTION "public"."global_var_set"
(in_key varchar, in_value bigint)
RETURNS bigint AS
$body$
my ($key, $value) = @_;
$_SHARED{$key} = $value;
return $value;
$body$
LANGUAGE 'plperl' VOLATILE RETURNS NULL ON NULL INPUT;
----------
Then, later you can read that global variable with another function like
this:
----------
CREATE OR REPLACE FUNCTION "public"."global_var_get"
(in_key varchar)
RETURNS bigint AS
$body$
my ($key) = @_;
return $_SHARED{$key} ? $_SHARED{$key} : 0;
$body$
LANGUAGE 'plperl' VOLATILE RETURNS NULL ON NULL INPUT;
----------
Perhaps you can use PL/PERL and a function like these to modify "global"
variables that you can increment as you do your select. Something like:
SELECT global_var_set(0);
SELECT global_var_inc() AS row_counter, *
FROM datatable
ORDER BY whatever;
Just an idea.
-- Dante
----------
D. Dante Lorenso
dante@lorenso.com
D. Dante Lorenso wrote:
PERL can remember variables in your session. Here's a function I wrote
that sets a "global" variable in PL/PERL:
Perl can do anything- that's cheating :-)
Actually, I use Perl heavily but the advantage of being able to do the
sort of analysis being discussed in a single query is that the query can
be easily shipped with the results as a description of the method.
Having to set up ad-hoc extra functions (in addition to those that are
normally in the workflow) can be problematic, particularly if a
recipient of the query only has restricted access.
--
Mark Morgan Lloyd
markMLl .AT. telemetry.co .DOT. uk
[Opinions above are the author's, not those of his employers or colleagues]
am Wed, dem 15.10.2008, um 12:23:42 -0700 mailte Richard Broersma folgendes:
On Wed, Oct 15, 2008 at 12:08 PM, ries van Twisk <pg@rvt.dds.nl> wrote:
May be this function can help :
http://www.postgresql.org/docs/8.3/static/functions-srf.html
Using generate series won't number the rows that way that you would
want. You basically will end up with a cross join between the
generated series and the requested set. There are three ways that I
know of to get a row number:1) IIRC use a pl-pgsql function that returns an incremented number
2) use SQL by joining using the operator ">=" and Group by aggregate count(*)
3) 8.4 has sum new analytic functions that will do this nicely.
Can you show an example for 8.4?
Andreas
--
Andreas Kretschmer
Kontakt: Heynitz: 035242/47150, D1: 0160/7141639 (mehr: -> Header)
GnuPG-ID: 0x3FFF606C, privat 0x7F4584DA http://wwwkeys.de.pgp.net
Andreas Kretschmer wrote:
Can you show an example for 8.4?
It's not 100% certain that it will be possible for 8.4, probably though.
select row_number() over (order by employeeid) as nrow,* from employee order
by employeeid
It's important to have both the order bys
There is more information on windowing functions here
http://en.wikipedia.org/wiki/SELECT
David.
David Rowley wrote:
It's not 100% certain that it will be possible for 8.4, probably though.
select row_number() over (order by employeeid) as nrow,* from employee order
by employeeid
That makes sense, thanks. So extracting rate-of-change etc. would be a
join on two subselects followed by a bit of maths, that's likely to be a
big incentive for an upgrade when it comes out.
--
Mark Morgan Lloyd
markMLl .AT. telemetry.co .DOT. uk
[Opinions above are the author's, not those of his employers or colleagues]
On Wed, Oct 15, 2008 at 10:21 PM, A. Kretschmer
<andreas.kretschmer@schollglas.com> wrote:
Can you show an example for 8.4?
I looked for ROW_NUMBER in the developer docs. I could only find it
under the KEY WORDS list. I guess they haven't put in a good example
yet.
I saw this recently demonstrated at PgWest by Dave Fetter. He
illustrated several example of how to use analytic functions such as
these.
http://fetter.org/Window_Functions_WEST_2008.pdf
http://fetter.org/Trees_and_More_WEST_2008.pdf
--
Regards,
Richard Broersma Jr.
Visit the Los Angeles PostgreSQL Users Group (LAPUG)
http://pugs.postgresql.org/lapug
"Richard Broersma" <richard.broersma@gmail.com> writes:
I looked for ROW_NUMBER in the developer docs. I could only find it
under the KEY WORDS list. I guess they haven't put in a good example
yet.
I saw this recently demonstrated at PgWest by Dave Fetter. He
illustrated several example of how to use analytic functions such as
these.
Fetter was demo'ing uncommitted patches.
regards, tom lane